Traditional Ruby Exception Handling
Every online blog post that I come across that talks about exception handling in Ruby starts off something like this:
begin
puts "some code that might cause an error"
rescue StandardError => e
puts "rescued"
end
A begin/rescue block is pretty much the cliche of Ruby exception handling, as is rescuing StandardError.
In fact, the traditional advice is that StandardError will capture the exceptions that a normal Ruby program is supposed to use.
But you don’t have to stick with cliches
Imagine my delight when one of my coworkers informed me that you don’t necessarily need to use begin. For example:
def get_money_details
geocoder_info = get_geocoder_info #some function that can trigger a ::Geocoder::Error
do_something_with_geocoder_info(geocoder_info) #some function to do something with geocoder_info
construct_money_details #some function that handles money details and can trigger a Binary::Errors::TaxError
rescue ::Geocoder::Error => e
@error_notifier.notify(e.message)
return construct_null_tax_details({status_message: e.message })
rescue Binary::Errors::TaxError => e
@error_notifier.notify(e.message, { type: Binary::Errors::TaxError::GENERAL_BINARY_TYPE})
return construct_null_tax_details({ status_message: e.message })
end
Note that I don’t use begin anywhere in the above code. If the geocoder_info
function raises a ::Geocoder::Error, then there’s a rescue block for that. If construct_money_details
raises a Binary::Errors::TaxError, then there’s a rescue block for that as well.
Compress to a single rescue block?
As mentioned in the blog post by Thoughtbot, you could come up with an array of errors and compress it to a single rescue block as follows:
ERRORS = [::Geocoder::Error, Binary::Errors::TaxError]
begin
#some function calll
rescue *ERRORS => e
#some rescue code
end
But since I needed to call the notify method with 2 different arguments, I opted to have a double rescue block.
But I think the code is a bit more compact and styled more nicely than it would have been had I used a begin keyword.