且构网

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

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

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

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

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.

另一种选择是修改突变,使其采用单个memberId.然后,您可以为要添加的每个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.