graphql - 记录 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 方法。
解决方案
可以使用 Union 或 Interface 来完成您想要完成的工作:
type Mutation {
addVoucher(id: ID!): AddVoucherPayload
}
union AddVoucherPayload = Order | VoucherError
您是对的,没有一种标准化的方法来处理用户可见的错误。对于某些实现,例如apollo-server
,可以在响应中返回的错误上公开其他属性,如此处所述。这确实使解析错误更容易,但仍然不理想。
最近出现了一种“有效负载”模式,用于将这些错误作为模式的一部分进行处理。您可以在Shopify等公共 API 中看到它。我们只使用一个对象类型,而不是上面示例中的联合:
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
}
一些实现也添加了status
orsuccess
字段,尽管我发现使实际的数据字段(order
是我们的示例)可以为空,然后在突变失败时返回 null 也足够了。我们甚至可以更进一步,添加一个接口来帮助确保我们的有效负载类型的一致性:
interface Payload {
errors: [Error!]!
}
当然,如果您想更细化并区分不同类型的错误以更好地记录哪些突变可以返回哪些错误集,您将无法使用接口。
我在这种方法上取得了成功,因为它不仅记录了可能的错误,而且使客户更容易处理它们。这也意味着响应返回的任何其他错误都应立即作为一个危险信号,表明客户端或服务器出现问题。YMMV。
推荐阅读
- c# - 我无法将频道设为私有
- java - 使用 JNA 实现 IContextMenu COM 接口
- html - Html - 显示whatsapp分享按钮内的链接文本
- reactjs - 获取选项后反应钩子未设置选择值
- html - 循环插值 SVG 精灵
- github - 在私有存储库的 GItHub 工作流中使用机密
- java - 数据绑定,MaterialCardView 应该像 Radiogroup
- laravel - 谈不上雄辩的关系
- javascript - 使用 php $_POST 的 Html Form 方法重新定位
- c# - 您可以使用 C# 在 ASP.NET 中触发 PostBack 吗?