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?