Where and how to handle rails exceptions?
I am currently involved in the development of a large rails application that interfaces with another product via a custom API gem. This has led to a very strange sort of error catching. For instance, when we interact with the other product, it might return an authentication error, which we expect. We then catch that error in our API gem and throw an exception, which is then caught and relayed to the user in the view.
I do not like this method of error catching for a few reasons:
- It doesn't seem like we should be expecting exceptions and using them in our logic. As an example, sometimes we want to overwrite an object -- so we catch the "object already exists" exception and go ahead and save our model anyway.
- It requires a lot of specific error catching. There are multiple areas in the code where we have if-elses checking for certain errors and redirecting accordingly.
That said, should I flesh out the API gem to have simpler functions that do not throw exceptions? Is
if user.has_permission_in_product?
if object.doesnt_exist_in_product?
do something
else
redirect somewhere with errors
end
else
redirect somewhere else with errors
end
preferable to
begin
do something
rescue APIError => e
if e.message =~ "no permission"
redirect somewhere with errors
elsif e.message =~ "already exists"
redirect somewhere else with errors
e开发者_如何学JAVAnd
end
Furthermore, if the first is preferable, how do we deal with actual API errors that may be thrown in those functions? Do we bubble those up into a rescue_from in the controller?
Is it better to catch and deal with exceptions in the model, or throw them in the model and deal with them in the controller?
Are you looking for rescue_from ?
In your controller, do the following :
class MyController < ApplicationController
rescue_from ActiveRecord::RecordNotFound, :with => :render_missing
def render_missing
render 'This is a 404', :status => 404
end
end
This will execute the render_missing method every time an ActiveRecord::RecordNotFound
exception is raised.
You can use it with any exception class you wish. And you don't need any begin/rescue in your controllers anymore.
Of course any exception raised in a model could also be caught by rescue_from.
精彩评论