GraphQL - Как реагировать с другим кодом состояния?

У меня проблемы с Graphql и Apollo Client.

Я всегда создавал разные ответы, такие как код 401, когда я использую REST, но здесь я не знаю, как мне делать подобное поведение.

Когда я получу ответ, я хочу, чтобы он перешел к функции catch. У меня есть этот код спереди:

client.query({
  query: gql`
    query TodoApp {
      todos {
        id
        text
        completed
      }
    }
  `,
})
  .then(data => console.log(data))
  .catch(error => console.error(error));

Может кто-нибудь мне помочь?

Ответ 1

Способ возврата ошибок в GraphQL (по крайней мере, в graphql-js) заключается в том, чтобы бросать ошибки внутри функций разрешения. Поскольку коды состояния HTTP специфичны для транспорта HTTP, а GraphQL не заботится о транспорте, нет никакого способа установить там код состояния. Вместо этого вы можете указать конкретную ошибку внутри своей функции разрешения:

age: (person, args) => {
  try {
    return fetchAge(person.id);
  } catch (e) {
    throw new Error("Could not connect to age service");
  }
}

Ошибки GraphQL отправляются клиенту в ответ так:

{
  "data": {
    "name": "John",
    "age": null
  },
  "errors": [
    { "message": "Could not connect to age service" }
  ]
}

Если сообщение недостаточно информации, вы можете создать специальный класс ошибок для вашего сервера GraphQL, который содержит код состояния. Чтобы убедиться, что код статуса включен в ваш ответ, вам нужно указать функцию formatError при создании промежуточного программного обеспечения:

app.use('/graphql', bodyParser.json(), graphqlExpress({ 
    schema: myGraphQLSchema,
    formatError: (err) => ({ message: err.message, status: err.status }),
}));

Ответ 2

Недавно в спецификацию было добавлено сообщение об ошибках:

Службы GraphQL могут предоставлять дополнительную запись об ошибках с ключевыми расширениями. Эта запись, если установлена, должна иметь карту в качестве значения. Эта запись зарезервирована для разработчиков, чтобы добавить дополнительную информацию об ошибках, как они считают нужным, и нет никаких дополнительных ограничений на ее содержание.

Теперь, используя поле extensions, вы можете настраивать машиночитаемую информацию для своих записей errors:

{
  "errors": [
    {
      "message": "Name for character with ID 1002 could not be fetched.",
      "locations": [ { "line": 6, "column": 7 } ],
      "path": [ "hero", "heroFriends", 1, "name" ],
      "extensions": {
        "code": "CAN_NOT_FETCH_BY_ID",
        "timestamp": "Fri Feb 9 14:33:09 UTC 2018"
      }
    }
  ]
}

Последняя версия Apollo-Server совместима со спецификацией этой функции. Проверьте здесь.

Ответ 4

В дополнение к ответу Гленна, здесь является частью спецификации Graphql, которая определяет, как следует обрабатывать ошибки. Таким образом, чтобы узнать, был ли запрос неудачным (или частично неудачным), вы можете проверить ключ "ошибки" в корне ответа.