且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在graphql解析器中同时返回错误和数据?

更新时间:2022-05-26 07:33:20

是否可以在不向返回类型添加错误字段的情况下解决此问题?

Is it possible to solve this problem without adding error field to the return type?

不幸的是,没有.

解析器可以返回数据,也可以返回 null 并抛出错误.它不能两者兼而有之.澄清一下,可能会得到部分响应和一些错误.一个简单的例子:

A resolver can either return data, or return null and throw an error. It cannot do both. To clarify, it is possible to get a partial response and some errors. A simple example:

const typeDefs = `
  type Query {
    foo: Foo
  }

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

在此示例中,查询 foo 上的两个字段将导致以下响应:

In this example, querying both fields on foo will result in the following response:

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

通过这种方式,可以同时发回数据和错误.但是你不能在同一个领域这样做,就像你的问题一样.有几种方法可以解决这个问题.正如您所指出的,您可以将错误作为响应的一部分返回,这通常是这样做的.然后,您可以使用 formatResponse,遍历结果数据,提取任何错误并将它们与任何其他 GraphQL 错误结合起来.不是最优的,但它可能会让你得到你正在寻找的行为.

In this way, it's possible to send back both data and errors. But you cannot do so for the same field, like in your question. There's a couple of ways around this. As you point out, you could return the errors as part of the response, which is usually how this is done. You could then use formatResponse, walk the resulting data, extract any errors and combine them with them with any other GraphQL errors. Not optimal, but it may get you the behavior you're looking for.

另一种替代方法是修改突变,使其采用单个成员 ID.然后,您可以为要添加的每个 ID 请求单独的更改:

Another alternative is to modify the mutation so it takes a single memberId. You can then request a separate mutation for each id you're adding:

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

这在处理客户端时可能会比较棘手,当然效率也较低,但同样可能会给您带来预期的行为.

This can be trickier to handle client-side, and is of course less efficient, but again might get you the expected behavior.