Как вернуть и ошибку, и данные в резольвере graphql? - PullRequest
0 голосов
/ 12 октября 2018

Я думал о способах реализации ответа graphql, который содержал бы как ошибку, так и данные.

Возможно ли это сделать без создания типа, который бы содержал error?

например,

Мутация addMembersToTeam(membersIds: [ID!]! teamId: ID!): [Member] добавляет членов в какую-то команду.Предположим, что эта мутация вызывается со следующими membersIds: [1, 2, 3].

Участники с идентификаторами 1 и 2 уже находятся в команде, поэтому необходимо выдать ошибку, что эти участники не могут быть добавлены, но участник сID 3 должен быть добавлен, поскольку он не в команде.

Я думал об использовании formatResponse, но мне кажется, что я не могу получить ошибку там.

Возможно ли решить эту проблему, не добавляя поле ошибки в тип возвращаемого значения?

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Возможно ли решить эту проблему без добавления поля ошибки к типу возвращаемого значения?

К сожалению, нет.

Средство распознавания может либо вернуть данные, либо вернутьобнулить и выкинуть ошибку.Это не может сделать оба.Чтобы уточнить, можно получить частичный ответ и некоторые ошибки.Простой пример:

const typeDefs = `
  type Query {
    foo: Foo
  }

  type Foo {
    a: String
    b: String
  }
`
const resolvers = {
  Query: {
    foo: () => {},
  }
  Foo: {
    a: () => 'A',
    b: () => new Error('Oops!'),
  }
}

В этом примере запрос к обоим полям на foo приведет к следующему ответу:

{
  "data": {
    "foo": {
      "a": "A",
      "b": null
    }
  },
  "errors": [
    {
      "message": "Oops",
      "locations": [
        {
          "line": 6,
          "column": 5
        }
      ],
      "path": [
        "foo",
        "b"
      ]
    }
  ]
}

Таким образом, можно отправить обаданные и ошибки.Но вы не можете сделать это для той же области, как в вашем вопросе.Есть несколько способов обойти это.Как вы указали, вы можете возвращать ошибки как часть ответа, как правило, так и делается.Затем вы можете использовать formatResponse, просмотреть полученные данные, извлечь любые ошибки и объединить их с любыми другими ошибками GraphQL.Не оптимально, но оно может дать вам то поведение, которое вы ищете.

Другая альтернатива - изменить мутацию так, чтобы она принимала один memberId.Затем вы можете запросить отдельную мутацию для каждого добавляемого вами идентификатора:

add1: addMemberToTeam(memberId: $memberId1 teamId: $teamId): {
  id
}
add2: addMemberToTeam(memberId: $memberId2 teamId: $teamId): {
  id
}
add3: addMemberToTeam(memberId: $memberId3 teamId: $teamId): {
  id
}

Это может быть сложнее для обработки на стороне клиента и, конечно, менее эффективно, но опять-таки может привести к ожидаемому поведению.

0 голосов
/ 12 октября 2018

Если вы думаете об объединении ошибки GraphQL - есть способ сделать это в Apollo.Вам нужно использовать errorPolicy для этого. Ссылка на документацию

Установка политики на all поможет вам уведомлять пользователей об ошибке и в то же время иметь как можно больше данных.

none : Это политика по умолчанию, соответствующая принципу работы Apollo Client 1.0.Любые ошибки GraphQL обрабатываются так же, как и сетевые ошибки, а любые данные игнорируются в ответе.

ignore : Ignore позволяет читать любые данные, которые возвращаются вместе с ошибками GraphQL, но не сохраняет ошибки и не сообщает о них в пользовательский интерфейс.

all : использование политики «все» - это лучший способ уведомить пользователей о потенциальных проблемах, при этом показывая с вашего сервера как можно больше данных.Он сохраняет как данные, так и ошибки в кэш-памяти Apollo, чтобы ваш пользовательский интерфейс мог их использовать.

Но в соответствии с рекомендациями, вам не следует манипулировать этим способом.Это отличная статья об обработке ошибок в GraphQL.

Итак, предпочтительным способом является добавление поля "errors" как части вашего ответа и обработка его в коде js.

...