Reputation: 20667
I'm creating an API in Rails and I've run into a situation where I'd like to alert the user that something bad happened by passing them some JSON with an error message. However, I'd also like to re-raise the exception so that Airbrake (formerly Hoptoad) will still catch the error and notify us so that we can look into the problem a bit more.
I'm currently catching the error like so:
begin
if @myobject.update_attributes(:foo => "bar")
render :json => @myobject, :status => :ok
else
render :json => @myobject.errors, :status => :unprocessable_entity
end
rescue Exception => e
render :json => { :errors => { :message => "Uh oh! Something went wrong." } }
raise e
end
The problem is that my client never gets the JSON message since the raise e
stops it from rendering and sends it a generic 500 error.
How should I fix this?
[My Solution]
As suggested by Jordan below, I simply call notify_airbrake(ex)
in my code any time that I catch the exception. However, I abstracted it slightly by adding the following to my ApplicationController
so that I can easily change from Airbrake to something else in the future:
class ApplicationController < ActionController::Base
...
def notify_exception_service(ex)
notify_airbrake(ex)
end
...
end
So, instead of notify_airbrake(ex)
I just call notify_exception_service(ex)
.
Upvotes: 3
Views: 2159
Reputation: 106027
From the Airbrake gem documentation:
If you want to log arbitrary things which you've rescued yourself from a controller, you can do something like this:
rescue => ex notify_airbrake(ex) flash[:failure] = 'Encryptions could not be rerouted, try again.' end
The
#notify_airbrake
call will send the notice over to Airbrake for later analysis. While in your controllers you use thenotify_airbrake
method, anywhere else in your code, useAirbrake.notify
.
You don't have to re-raise the exception in order to log it with in Airbrake.
Upvotes: 3
Reputation: 11689
As I've said on chat, I think you can't becouse of how rails render things. When you call render, a @_something_render_variable is set, but the page is not directly render, there is still additional call. Raising an exception obviusly block this flow, actually breaking the render of the webpage.
Changing this behaviour is really hard, you must alias the render method and work on it, I had a similar problem.
Upvotes: 2