Description
Hello,
As documented here the new GraphQL::Execution::Interpreter
does not work with the rescue_from
middleware. I think the rescue_from add valuable error handeling that allows your endpoint to always return a 200 and indicate the errors. The following examples are based of the graphql-errors
gem which we currently use https://github.com/exAspArk/graphql-errors
The most common example is catching ActiveRecord::RecordNotFound
and replace them with nil
so whenever you try to fetch something that does not exist you return a 200 with nothing in it.
rescue_from ActiveRecord::RecordNotFound do |_exception|
nil
end
Another example is to error standardisation, for example in our GraphQL api we always call update!
or save!
this raises a ActiveRecord::RecordInvalid
which we capture with rescue_from and standarize the error response:
rescue_from ActiveRecord::RecordInvalid do |exception|
RecordInvalidError.from_exception(exception)
end
class RecordInvalidError < GraphQL::ExecutionError
def to_h
super.merge(problems: extensions[:errors])
end
def self.from_exception(exception)
record = exception.record
errors = record.errors.map do |attr|
{
path: [attr.to_s.camelize(:lower)],
explanation: record.errors.full_messages_for(attr)
}
end
new(record.errors.full_messages.join("\n"), extensions: { errors: errors })
end
end
Ofcourse one can say that every mutation / resolver should deal with the errors themself, but this means that you always have to go for a if ...save else do_with_errors end
kind of thing which isn't that pretty nor ensures consistency.
Finally sometimes (even when you know its bad) you have some deeply nested code where you want to brake out of so your only resort is to raise an exception, this does not mean you want to return back a 500 but rather a customised message.
If anyone else has other use cases then please do share,
Regards