views:

173

answers:

1

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
  end
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?

+4  A: 

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.

Damien MATHIEU
I do know about rescue_from. I suppose a more relevant question for me to ask would be: Is it bad practice (and if so, why?) to use exceptions to control my application? Should I try to avoid exceptions whenever possible?
NolanDC