记录GraphQL服务器上的所有潜在错误?

时间:2019-04-10 13:32:57

标签: graphql

对于突变addVoucher,可能发生的潜在错误列表非常有限。

  • 优惠券代码无效
  • 优惠券已过期
  • 优惠券已经兑换

目前,当其中一种情况发生时,我将引发自定义错误。

// On the server:
const addVoucherResolver = () => {
    if(checkIfInvalid) {
        throw new Error('Voucher code invalid')
    }
    return {
        // data
    }
}

然后在客户端上搜索消息描述,以便向用户发出警报。但是,这感觉很脆弱,而且GraphQL API不会自动记录潜在的错误。有没有办法在GraphQL模式中定义潜在错误?

当前我的模式如下:

type Mutation {
    addVoucherResolver(id: ID!): Order
}

type Order {
    cost: Int!
}

能够做这样的事情很好:

type Mutation {
    addVoucherResolver(id: ID!): Order || VoucherError
}

type Order {
    cost: Int!
}

enum ErrorType {
    INVALID
    EXPIRED
    REDEEMED
}

type VoucherError {
    status: ErrorType!
}

那么使用该API的任何人都将知道所有潜在的错误。对我来说,这似乎是一个标准要求,但是从阅读的角度来看,似乎没有一个标准化的GraphQL方法。

2 个答案:

答案 0 :(得分:1)

可以使用联合或接口来完成您要完成的任务:

type Mutation {
  addVoucher(id: ID!): AddVoucherPayload
}

union AddVoucherPayload = Order | VoucherError

您是对的,没有一种处理用户可见错误的标准化方法。对于某些实现,例如apollo-server,可以对响应中返回的错误公开其他属性,如here所述。这确实使解析错误更加容易,但是仍然不理想。

最近出现了一种“有效负载”模式,用于将这些错误作为模式的一部分进行处理。您可以在Shopify's之类的公共API中看到它。除了使用上面的示例中的Union之外,我们仅使用Object Type:

type Mutation {
  addVoucher(id: ID!): AddVoucherPayload
  otherMutation: OtherMutationPayload
}

type AddVoucherPayload {
  order: Order
  errors: [Error!]!
}

type OtherMutationPayload {
  something: Something
  errors: [Error!]!
}

type Error {
  message: String!
  code: ErrorCode! # or a String if you like
}

enum ErrorCode {
  INVALID_VOUCHER
  EXPIRED_VOUCHER
  REDEEMED_VOUCHER
  # etc
}

某些实现还添加了statussuccess字段,尽管我发现使实际数据字段(order是我们的示例)为空,然后在突变失败时返回null也足够了。我们甚至可以更进一步,并添加一个接口来帮助确保我们的有效负载类型之间的一致性:

interface Payload {
  errors: [Error!]!
}

当然,如果您想更细化并区分不同类型的错误,以更好地记录哪种变异可以返回哪些错误集,则将无法使用界面。

我在这种方法上取得了成功,因为它不仅记录了可能的错误,而且使客户更容易处理它们。这还意味着,随响应返回的任何 other 错误都应立即作为警告信号,表明客户端或服务器出现了问题。 YMMV。

答案 1 :(得分:0)

您可以使用graphql中存在的标量类型 只需编写scalar JSON并返回要返回的JSON类型即可。

`
  scalar JSON
  type Response {
    status: Boolean
    message: String
    data: [JSON]
  }
`

这里是变异,会返回响应

  `
  type Mutation {
    addVoucherResolver(id: ID!): Response
  }
`

您可以从解析器返回

return {
      status: false,
      message: 'Voucher code invalid(or any error based on condition)',
      data: null
  }

return {
      status: true,
      message: 'Order fetch successfully.',
      data: [{
          object of order
      }]
  }

在前端,您可以使用状态键来识别响应是提取还是发生错误。