Skip to content

GraphQL::Execution::Interpreter and rescue_from compatibility #2139

Closed
@JanStevens

Description

@JanStevens

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

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions