0
votes

I am creating my first Web Service using Grape and I am confused by one thing. How do I respond with ActiveRecord validation errors when a POST request does not pass AR validation?

In my Foo model I have this:

validates :bar, { 
        presence:   true, 
        uniqueness: true
    }

My Foo Create API in Grape looks like this:

desc "Create a new Foo"
params do
  requires :bar, type: String, allow_blank: false
end
post do
  ::Foo.create!({
    bar: params[:bar]
  })
end

As an example, when I create a Foo with Duplicate Bar, I am presented with a standard Rails Error page (Using Postman). How do I make sure that all my errors are only returned as JSON objects?

PS. I have the following instructions set up in my API class:

default_format :json
format :json
formatter :json, Grape::Formatter::ActiveModelSerializers
2

2 Answers

2
votes

You can use in your API module the method rescue_from with a parameter ActiveRecord::RecordInvalid which I consider as a more elegant way to achieve what you are intending to do. Passing a block to that method will allow you to obtain the error message and process it further. So that you will get a uniform way in treating all validation errors. For example:

rescue_from ActiveRecord::RecordInvalid do |error|
  message = error.record.errors.messages.map { |attr, msg| msg.first }
  error!(message.join(", "), 404)
end
0
votes

Here is a simple example:

  get "" do
    begin
      present Region.find(params[:id])
    rescue ActiveRecord::RecordNotFound => e
      not_found_error(e)
    end
  end

So I created simple helper:

module YourApi::V1::ErrorsHelper
  def not_found_error(e)
    error!({ error: { message: "#{e.message}", error: "#{e.class} error", code: 404 }}, 404)
  end
end

So, just use the method error! and handle using the way that you want, with message, type and code.