Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to handle exceptions in JSON based RESTful code?

I have a "software as a service" app that uses JSON communicated via a RESTful API.

Simply stated: what are the best practices for capturing and reporting exceptions when using a RESTful API with JSON data interchange?

My first thought was to see what Rails does by generating a scaffold, but that's clearly not right. Here's an excerpt:

class MumblesController < ApplicationController    # GET /mumbles/1   # GET /mumbles/1.json   def show     @mumble = Mumble.find(params[:id])     respond_to do |format|       format.html # show.html.erb       format.json { render json: @mumble }     end   end  end 

In this case, if the JSON code sends a non-existent ID, e.g.

http://www.myhost.com/mumbles/99999.json 

then Mumble.find() will raise ActiveRecord::RecordNotFound. ActionController will catch that and render an error page in HTML. But HTML is useless to the client that is expecting JSON.

I could work around that by wrapping the Mumble.find() in a begin ... rescue RuntimeError block and rendering a JSON status => :unprocessable_entity or something.

But then what if the client's app sends an invalid path, e.g.:

http://www.myhost.com/badtypo/1.json 

Is a JSON based app supposed to catch that and return an error in JSON? If so, where do I capture that without digging deep into ActionDispatch?

So overall, do I punt and let ActionController generate HTML if there's an error? That doesn't feel right...

like image 953
fearless_fool Avatar asked Aug 08 '12 07:08

fearless_fool


People also ask

How do you handle exceptions in REST API?

To deal with exceptions, the recommended practice is to follow the sequence outlined below: Determine whether the REST API request succeeded or failed, based on the HTTP status response code returned. If the REST API request failed and the response is application/json, serialize the model.

How do you handle exceptions in spring boot REST API?

Altogether, the most common way is to use @ExceptionHandler on methods of @ControllerAdvice classes so that the exception handling will be applied globally or to a subset of controllers. ControllerAdvice is an annotation introduced in Spring 3.2, and as the name suggests, is “Advice” for multiple controllers.

How does REST API handle error response?

The most basic way of returning an error message from a REST API is to use the @ResponseStatus annotation. We can add the error message in the annotation's reason field. Although we can only return a generic error message, we can specify exception-specific error messages.


2 Answers

(I found the answer just before I hit [Post your question]. But this might help someone else as well...)

Use ActionController's rescue_from

The answer is to use ActionController's rescue_from, as described in this Guide and documented here. In particular, you can replace the default rendering of the default 404.html and 500.html files along these lines:

class ApplicationController < ActionController::Base   rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found  private   def record_not_found(error)     render :json => {:error => error.message}, :status => :not_found   end  end 
like image 156
fearless_fool Avatar answered Oct 06 '22 05:10

fearless_fool


If it helps anyone, this is what I did as a catch all for my purely json api:

In your ApplicationController that each specific controller inherits from, add

# app/controllers/api/v1/application_controller.rb  # ...  rescue_from StandardError do |exception|     render json: { :error => exception.message }, :status => 500 end  # ... 
  • based mostly off fearless_fool's answer
like image 36
Tim S Avatar answered Oct 06 '22 03:10

Tim S