how to handle exceptions in JSON based RESTful code?
(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_foundprivate def record_not_found(error) render :json => {:error => error.message}, :status => :not_found end end
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 => 500end# ...
- based mostly off fearless_fool's answer
As a developer, you will also want to see traces (preferably with useful lines, filtering out gems). And make traces invisible for production:
rescue_from StandardError do |exception| # Handle only JSON requests raise unless request.format.json? err = {error: exception.message} err[:backtrace] = exception.backtrace.select do |line| # filter out non-significant lines: %w(/gems/ /rubygems/ /lib/ruby/).all? do |litter| not line.include?(litter) end end if Rails.env.development? and exception.is_a? Exception # duplicate exception output to console: STDERR.puts ['ERROR:', err[:error], ''] .concat(err[:backtrace] || []).join "\n" render :json => err, :status => 500 end