This week at work we struggled to find a nice way to rescue an exception (OpenURI::HTTPError) in a way that doesn’t look terrible. Digging into the internet, there wasn’t much information so I decided to post our solution here, it may be not the perfect one, but it was the best we could get…
In our context, from time to time, we go to a url and check if it’s already available, otherwise we get a 404, which is perfectly expected in our case. To avoid NewRelic to warn us every single time with this error, we decided to catch only the 404 error and try again (it’s a Sidekiq job) until a certain amount of times.
require 'open-uri'
def check_if_url_is_available
url = open('http://your-web-site.com/file.txt')
rescue OpenURI::HTTPError => e
raise FileNotReady if e.io.status[0] == 404
raise e
end
class FileNotReady < StandardError; end
In this way, we’re able to add this class FileNotReady as an exception for NewRelic.
If you go the the OpenURI::HTTPError
documentation you can see that there are two arguments: message and io, the last one is the one we need to check the code. In our case, message would be 404 Not found.
How can we test this?
require 'spec_helper'
describe FooClass
context '#check_if_url_is_available' do
context 'raising 404 Not found' do
before do
io = double(:io, status: [404, 'Not found'])
allow_any_instance_of(described_class).to
receive(:open).and_raise(
OpenURI::HTTPError.new('404 Not found', io)
)
end
end
it { expect { subject }.to raise_error(FileNotReady) }
end
end
Hope this can help you! Cheers.