9

I am using Grape and Rails to create a REST API. I have the basic architecture in place and I am looking for places to 'clean' things up. One of those places is the error handling/processing.

I am currently rescuing errors in the root.rb (GRAPE::API base class) file for the whole API. I format them and then send the error back via rack_response. Everything works find but the root.rb file is getting a bit bloated with all the errors being rescued and some of them have special parsing that needs to be done. I was wondering if anyone has developed a good strategy for error handling so that it can be moved out into it's own module and leave the root.rb (GRAPE::API base class) fairly lean.

I would really like to create a error processing module and define methods for each type of error, for example...

module API
 module ErrorHandler
   def record_not_found
     rack_response API::Utils::ApiErrors.new({type: e.class.name, message: 'Record not found'}).to_json, 404
   end
 end
end

Then in the root.rb file do something like this

module API
  class Root < Grape::API
    prefix 'api'
    format :json

    helpers API::ErrorHandler

    rescue_from ActiveRecord::RecordNotFound, with: :record_not_found # Use the helper method as the handler for this error
  end
end

Has anyone done something like this? I have been trying various flavors of the above strategy but I can't seem to get anything work.

mfunaro
  • 574
  • 6
  • 23
  • Take a look [Here](https://github.com/intridea/grape/issues/177) seems like it was/is a feature request but also seems like people have found a work around for now. – engineersmnky Oct 23 '14 at 13:56
  • Not quite the same thing I was looking for but definitely some ideas to think about in the link. Thanks. – mfunaro Oct 23 '14 at 14:34

1 Answers1

7

I've come to the following solution/strategy...

I moved all error rescuing to its own module like the following

module API
  module Errors
    extend ActiveSupport::Concern

    included do
      rescue_from :all do |e|
        rack_response API::Utils::ApiErrors.new({type: e.class.name, message: e.message}).to_json, 500
      end
      .
      .
      .
  end
end

Then I simply include the errors in my base GRAPE::API class

module API
  class Root < Grape::API
    include API::Errors

    prefix 'api'
    format :json

    helpers API::Utils::Helpers::IndexHelpers
    helpers API::Utils::Helpers::WardenHelpers
    helpers API::Utils::Helpers::RecordHelpers
    .
    .
    .
  end
end

After a lot of experimentation and a lot of other attempts not working, I think this is a fine solution and my base GRAPE::API class remains pretty lean. I am still very open to any other approaches people might have.

Jim Ferrans
  • 30,582
  • 12
  • 56
  • 83
mfunaro
  • 574
  • 6
  • 23
  • No, I do have a 'catch all' 500, but I rescue from other errors setting the status code to what is appropriate for the error. For example we rescue custom unprocessable errors and set their status code to 422. – mfunaro Feb 24 '16 at 20:17