GraphQL 规范 http://spec.graphql.org/October2021/#sec-Errors定义了明确的格式error
响应中的条目。
根据规范,它应该是这样的(假设使用 JSON 格式):
"errors": [
{
"message": "Name for character with ID 1002 could not be fetched.",
"locations": [ { "line": 6, "column": 7 } ],
"path": [ "hero", "heroFriends", 1, "name" ]
"extensions": {/* You can place data in any format here */}
}
]
因此,您不会找到允许您扩展它并在 GraphQL 执行结果中返回类似内容的 GraphQL 实现,例如:
"errors": [
{
"errorMessage": "Name for character with ID 1002 could not be fetched.",
"errorCode": 404
}
]
但是,该规范允许您以任何格式添加数据extension
入口。因此,您可以在服务器端创建一个自定义异常,并最终得到如下 JSON 所示的响应:
"errors": [
{
"message": "Name for character with ID 1002 could not be fetched.",
"locations": [ { "line": 6, "column": 7 } ],
"path": [ "hero", "heroFriends", 1, "name" ]
"extensions": {
"errorMessage": "Name for character with ID 1002 could not be fetched.",
"errorCode": 404
}
}
]
在 GraphQL Java 上实现这一点非常容易,如中所述the docs https://www.graphql-java.com/documentation/execution。您可以创建一个自定义异常来覆盖getExtensions
方法并在实现中创建一个映射,然后用于构建extensions
:
public class CustomException extends RuntimeException implements GraphQLError {
private final int errorCode;
public CustomException(int errorCode, String errorMessage) {
super(errorMessage);
this.errorCode = errorCode;
}
@Override
public Map<String, Object> getExtensions() {
Map<String, Object> customAttributes = new LinkedHashMap<>();
customAttributes.put("errorCode", this.errorCode);
customAttributes.put("errorMessage", this.getMessage());
return customAttributes;
}
@Override
public List<SourceLocation> getLocations() {
return null;
}
@Override
public ErrorType getErrorType() {
return null;
}
}
然后您可以从数据获取器内部抛出传递代码和消息的异常:
throw new CustomException(400, "A custom error message");
现在,有另一种方法可以解决这个问题。
假设您正在开发 Web 应用程序,您can以您想要的任何格式返回错误(和数据)。虽然在我看来这有点尴尬。 GraphQL 客户端(例如 Apollo)遵守规范,那么为什么要返回任何其他格式的响应呢?但无论如何,有很多不同的要求。
一旦你掌握了一个ExecutionResult
,您可以以任何您想要的格式创建映射或对象,将其序列化为 JSON 并通过 HTTP 返回。
Map<String, Object> result = new HashMap<>();
result.put("data", executionResult.getData());
List<Map<String, Object>> errors = executionResult.getErrors()
.stream()
.map(error -> {
Map<String, Object> errorMap = new HashMap<>();
errorMap.put("errorMessage", error.getMessage());
errorMap.put("errorCode", 404); // get the code somehow from the error object
return errorMap;
})
.collect(toList());
result.put("errors", errors);
// Serialize "result" and return that.
但同样,在大多数情况下,不符合规范的响应是没有意义的。