Hommer Smith
Hommer Smith

Reputation: 27862

Return proper errors from API in Rails

I have the following #create method:

def create
    begin
      @order = @api_user.orders.create!(order_params)
      render :json => @order, :only => [:id], :status => :created, :location => @order
    rescue
      render :json => {}, :status => :unprocessable_entity
    end
end

However, I am using a generalistic approach for the rescue. If the order could not be created because one of the passed fields failed the validation, I would like to let the user know about that. So, if the creation of the order raised this:

ActiveRecord::RecordInvalid: Validation failed: Description1 is too long (maximum is 35 characters)

What is the proper way of catching and letting the API user know about it?

Upvotes: 1

Views: 229

Answers (2)

John Naegle
John Naegle

Reputation: 8257

Here is another way:

def create
  @order = @api_user.orders.build(order_params)
  if @order.save
    render :json => @order, 
      :only => [:id], :status => :created, :location => @order
  else
    render :status => :unprocessable_entity, 
      :json => {:errors => @order.errors.full_messages}
  end
end

You'll get back an array of errors in the JSON

Upvotes: 0

derekyau
derekyau

Reputation: 2946

One thing you can do is make use of a light API library like rocketpants (https://github.com/Sutto/rocket_pants)

in which case, the method you want could be written like this:

def create
   if @order = @api_user.orders.create!(order_params)
      expose @order
   else
    error! :bad_request, :metadata => {:error_description => "#{@order.errors.full_messages}"}
   end
end

This is assuming you have set the @api_user instance variable earlier somewhere. Also, the gem uses Active Model Serializers (https://github.com/rails-api/active_model_serializers) to serialize the @order into JSON, so you can always customize the output to your liking by creating a basic serializer, look at the github page for more info :)

Upvotes: 1

Related Questions