Easy Hot Chocolate GraphQL Error Handling
Published 2020-06-05
Photo by Vitaly Eroshenko on Unsplash
Hot Chocolate is a platform to build GraphQL APIs in .NET Core and .NET Framework. In this article I'll go over an easy and consistent way to handle errors.
GraphQL Error Theory 📢
First off, GraphQL errors are a little different than REST API errors.
In REST to handle an error, you would carefully set an HTTP status code on the response and if needed more details could be added to the response body.
REST response example: GET /users/123
where user 123
does not exist:
// httpStatusCode = 404 not found
{
"error": {
"message": "user not found",
"code": "someErrorCode"
}
}
With GraphQL, a response will only have a 200 OK HTTP status code. In short, the theory is that HTTP status codes are transport layer concerns and if the transport succeeded (regardless of server-side issues) then respond with 200 OK.
Error details are only included in the body of the response as an array of errors.
Errors in Hot Chocolate ☕
By default, throwing an error in a query, mutation, or resolver will cause Hot Chocolate to create an instance of IError
with the message of Unexpected Execution Error
.
Consider this code for attempting to login a user (AppException
is a custom exception, nothing fancy):
var applicationUser = await GetUserByEmail(email);
if (applicationUser == null)
{
throw new AppException($"Cannot find user with email {email}");
}
When the user is not found, the server will respond with:
{
"errors": [
{
"message": "Unexpected Execution Error",
"locations": [
{
"line": 2,
"column": 3
}
],
The default Unexpected Execution Error
message can be overridden with an Error Filter to transform the IError
instance.
Inherit from IErrorFilter
and do your transformations in the OnError
method. Access to the thrown exception is in error.exception
.
public class GraphQLErrorFilter : IErrorFilter
{
public IError OnError(IError error)
{
return error.WithMessage(error.Exception.Message);
}
}
Then register the filter in Startup.cs
services.AddErrorFilter<GraphQLErrorFilter>();
A meaningful message is now in the message field:
{
"errors": [
{
"message": "Cannot find user with email test@test.com",
"locations": [
{
"line": 2,
"column": 3
}
],
Happy coding 👩💻
#asp.net core#graphql