如何使用 express-graphql 引发多个错误?
Posted
技术标签:
【中文标题】如何使用 express-graphql 引发多个错误?【英文标题】:How to throw multiple errors with express-graphql? 【发布时间】:2019-03-03 01:37:47 【问题描述】:在 express-graphql 应用程序中,我有一个 userLogin
解析器,如下所示:
const userLogin = async ( id, password ), context, info) =>
if (!id)
throw new Error('No id provided.')
if (!password)
throw new Error('No password provided.')
// actual resolver logic here
// …
如果用户没有提供id
和password
,它只会抛出一个错误。
"errors": [
"message": "No id provided.",
"locations": [
"line": 2,
"column": 3
],
"path": [
"userLogin"
]
],
"data":
"userLogin": null
如何在errors
响应数组中抛出多个错误?
【问题讨论】:
也许它已经过时了,但实现这一点的一种方法是检查它是否是一个数组,然后检查元素是否错误。你会在这里找到一个主题:github.com/graphql/graphql-js/issues/205 @LPK 是的,这是同一个问题,但我不明白他们是如何解决的…… 我不知道graphql
,但我有一个想法。你可以抛出一个Json字符串,可能会出现所有错误。
【参考方案1】:
没有办法在 javascript 中抛出一系列错误,或者让一个解析器拒绝多个错误。 GraphQL 响应包含一个 errors
数组,而不仅仅是一个 error
对象,因为当这些错误源自不同字段时,总响应可以包含多个错误。考虑一下这个架构和解析器:
type Query
a: String
b: String
c: String
const resolvers =
Query:
a: () => throw new Error('A rejected') ,
b: () => throw new Error('B rejected') ,
c: () => 'Still works!',
,
如果查询所有三个字段...
查询 一种 b C
您的数据将如下所示:
"errors": [
"message": "A rejected",
"locations": [
"line": 2,
"column": 3
],
"path": [
"a"
]
,
"message": "B rejected",
"locations": [
"line": 3,
"column": 3
],
"path": [
"b"
]
],
"data":
"a": null,
"b": null,
"c": "Still works!"
这是因为 GraphQL 支持部分响应。但是,请记住,这是可行的,因为这些字段可以为空。如果它们不为空,则这些错误将为bubble up to the closest nullable parent field。
以下是一些替代方法:
您可以利用formatError
更改 GraphQL 返回的错误如何显示给客户端。这意味着您可以在错误中包含任何类型的额外信息,例如错误代码或多个错误消息。一个简单的例子:
// The middleware
app.use('/graphql', graphqlExpress(
schema: schema,
formatError: (error) => (
message: error.message,
path: error.path,
locations: error.locations,
errors: error.originalError.details
)
))
// The error class
class CustomError extends Error
constructor(detailsArray)
this.message = String(details)
this.details = details
// The resolver
const userLogin = async ( id, password ), context, info) =>
const errorDetails = []
if (!id) errorDetails.push('No id provided.')
if (!password) errorDetails.push('No password provided.')
if (errorDetails.length) throw new CustomError(errorDetails)
// actual resolver logic here
你的回复看起来更像这样:
"errors": [
"message": "[No id provided.,No password provided.]",
"locations": [
"line": 2,
"column": 3
],
"path": [
"userLogin"
]
"errors" [
"No id provided.",
"No password provided."
]
],
"data":
"userLogin": null
也就是说,将面向用户的错误消息与 GraphQL 验证错误一起返回有点令人讨厌。一些 API 采用的另一种方法是在实际突变响应旁边包含一个 errors
字段。例如:
type Mutation
userLogin: UserLoginResponse
type UserLoginResponse
response: User
errors: [String!]
你也可以使用联合来达到类似的效果:
type Mutation
userLogin: UserLoginResponse
type Errors
errors: [String!]!
union UserLoginResponse = User | Errors
【讨论】:
感谢您的回答。我喜欢你建议的第二个解决方案。也就是说,我有 2 个问题: 1. 我可以用你的想法先制作一组错误消息,然后抛出一个简单的错误。在这里犯自定义错误有什么意义? 2.有没有办法在graphQL响应中的errors
数组中抛出多个错误(我的原始问题)?
对不起,我不够清楚。据我所知,无法在 js 中引发多个错误,也无法将它们的数组传递给 GraphQL。上面介绍了一些解决该限制的方法。创建自定义错误类并不是绝对必要的——您可以只创建一个普通错误,然后在其上设置details
属性。以上是关于如何使用 express-graphql 引发多个错误?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Express-GraphQL 的 GraphQL 订阅
如何在没有 Apollo Server 但使用 express-graphql 的情况下使用 apollo-datasource-rest
使用 Express-GraphQL 和 React-Apollo 订阅 GraphQL