GraphQL endpoints, we can expose errors as part of our schema. We should check errors fields to see if any errors in result data. For example if we query a field which is not existing in type system, we will get a error response. This type of errors is not supposed to be displayed to end users. It helps with debugging, error tracking etc.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"errors": [
{
"message": "Field 'user' doesn't exist on type 'Article'",
"locations": [
{
"line": 5,
"column": 5
}
],
"fields": [
"query",
"article",
"user"
]
}
]
}
For example, we could add errors to ArticleType:
1
2
3
4
5
6
7
8
ArticleType = GraphQL::ObjectType.define do
name "Article"
field :title, types.String
# ...
field :errors, types[types.String] do
resolve -> (obj, args, ctx) { obj.errors.full_messages }
end
end
1
2
3
4
5
6
7
mutation {
createArticle(article: {title: "GraphQL is Nice"}) {
id
title
errors # in case the save failed
}
}
1
2
3
4
5
6
7
8
9
10
11
resolve -> (obj, args, ctx) {
article_params = args["article"].to_h
begin
article = Article.create!(post_params)
# on success, return the article:
article
rescue ActiveRecord::RecordInvalid => err
# on error, return an error:
GraphQL::ExecutionError.new("Invalid input for Article: #{article.errors.full_messages.join(", ")}")
end
}
For example, we could make an object that wraps another resolver:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Wrap field resolver `resolve_func` with a handler for `error_superclass`.
# `RescueFrom` instances are valid field resolvers too.
class RescueFrom
def initialize(error_superclass, resolve_func)
@error_superclass = error_superclass
@resolve_func = resolve_func
end
def call(obj, args, ctx)
@resolve_func.call(obj, args, ctx)
rescue @error_superclass => err
# Your error handling logic here:
# - return an instance of `GraphQL::ExecutionError`
# - or, return nil:
nil
end
end
1
2
3
4
field :create_article, ArticleType do
# Wrap the resolve function with `RescueFrom.new(err_class, ...)`
resolve RescueFrom.new(ActiveRecord::RecordInvalid, -> (obj, args, ctx) { ... })
end
Reference: GraphQL Ruby website