Спецификация GraphQL определяет четкий формат для записи error
в ответе.
В соответствии со спецификацией, оно должно выглядеть так (при условии использования формата JSON):
"errors": [
{
"message": "Name for character with ID 1002 could not be fetched.",
"locations": [ { "line": 6, "column": 7 } ],
"path": [ "hero", "heroFriends", 1, "name" ]
"extension": {/* 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" ]
"extension": {
"errorMessage": "Name for character with ID 1002 could not be fetched.",
"errorCode": 404
}
}
]
Это довольно легко реализовать на GraphQL Java, как описано в документах . Вы можете создать пользовательское исключение, которое переопределяет метод 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");
Теперь есть другой способ решения этой проблемы.
Предполагая, что вы работаете с веб-приложением, вы можете возвращать ошибки (и данные в этом отношении) в любом формате, который вы хотите. Хотя это немного неловко, на мой взгляд. Клиенты 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.
Но опять же, иметь ответ, который не соответствует спецификации, не имеет смысла в большинстве случаев.