Нет способа выбросить массив ошибок в 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!',
},
}
Если вы запросите все три поля ...
query {abc}
Ваши данные будут выглядеть примерно так:
{
"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 поддерживает частичные ответы.Однако имейте в виду, что это работает, потому что поля обнуляются.Если бы они были ненулевыми, эти ошибки всплыли бы до ближайшего родительского поля, которое можно обнулять .
Вот некоторые альтернативные подходы:
Выможет использовать 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