graphql-java 错误数据(如扩展)被填充到客户端的 "message" 字段中

graphql-java error data (like extensions) is being stuffed into "message" field on client

在 graphql-java 中,我重写了 GraphQLError 上的 getExtensions,以便传递 "code" 扩展供 Apollo Client 使用。

当我添加断点时,我可以看到 GraphQLObjectMapper 在 executionResult 及其所有字段中看到错误,包括按预期正确设置的扩展。

但是,当错误到达 apollo 时,它会发生奇怪的变形,并且整个错误对象(包括扩展数组)看起来像这样被塞进了字符串消息字段中:

    {
  "errors": [
    {
      "message": "Unexpected error value: { message: \"Exception while fetching data (/myQuery) : Didn't work\", locations: [[Object]], path: [\"myQuery\"], extensions: { code: \"MY_CODE\", classification: \"DataFetchingException\" } }",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "mailLabels"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR"
      }
    }
  ],
  "data": null
}

据我所知,阿波罗没有做错任何事。我怀疑 graphql-java 可能是将整个错误填充到 "message" 字段中的那个”,然后将代码设置为 "INTERNAL_SERVER_ERROR",但我不太确定。是否存在我可以在 graphql-java 端做些什么来防止这种情况并使其正确传递扩展而不是将它们填充到消息值中?任何帮助将不胜感激。

不是graphql-java引起的,而是graphql-java-servlet引起的。在某些旧版本中,默认情况下它不会GraphQLError序列化为GraphQL规范定义的结构,这应该在issue.

中在7.5.1中修复。

如果您无法升级到最新版本,最简单的方法是自定义 GraphQLObjectMapper 并覆盖其 convertSanitizedExecutionResult :

public class CustomObjectMapper extends GraphQLObjectMapper {

    @Override
    public Map<String, Object> convertSanitizedExecutionResult(ExecutionResult executionResult, boolean includeData) {
        Map<String, Object>  result = super.convertSanitizedExecutionResult(executionResult, includeData);
        if(result.containsKey("errors")){
            result.put("errors", executionResult.getErrors().stream().map(err->err.toSpecification()).collect(toList()));
        }
    }
}