graphql-java 错误数据(如扩展)被填充到客户端的“消息”字段中

Posted

技术标签:

【中文标题】graphql-java 错误数据(如扩展)被填充到客户端的“消息”字段中【英文标题】:graphql-java error data (like extensions) is being stuffed into "message" field on client 【发布时间】:2020-06-19 16:18:51 【问题描述】:

在 graphql-java 中,我在 GraphQLError 上覆盖 getExtensions,以便传递 Apollo 客户端使用的“代码”扩展。

当我添加断点时,我可以看到 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可能是将整个错误填充到“消息”字段中,然后将代码设置为“INTERNAL_SERVER_ERROR”,但我不太确定。有什么我可以在graphql上做的吗? java end 以防止这种情况并使其正确传递扩展名而不是将它们填充到消息值中?任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

不是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()));
        
    

【讨论】:

谢谢肯。我正在运行 graphql-java-servlet 8.0.0,但我现在也确认它发生在 9.0.1 中。不过,我将尝试自定义 GraphqlObjectMapper

以上是关于graphql-java 错误数据(如扩展)被填充到客户端的“消息”字段中的主要内容,如果未能解决你的问题,请参考以下文章

使用 SQLite 数据库错误填充可扩展列表视图

environment.getArgument 无法在 graphql-java 中转换为我自己的 java 对象

如何在 Graphql-Java 中处理运行时多态性

在 graphql-java 中注册自定义标量

避免在 WCF 数据协定中填充扩展属性

突变查询 graphql-java