A common pattern in our apps is handling failure by notifying Hoptoad. A good example is hitting a third party web service, Twitter, from Thunder Thimble.
def fetch_tweets(search)
search.fetch
rescue *(HTTP_ERRORS + Twitter::Search::ERRORS) => error
HoptoadNotifier.notify(error)
[]
end
We send rescued errors to Hoptoad, shielding our users from 500s with relevant copy.

This code uses John Nunemaker’s Twitter gem. The Twitter gem nicely allows the separation of building a query (object initialization) and making the HTTP request (fetch method).
So, somewhere else, we do heavy-duty query building. We can then isolate the HTTP request inside it’s own one-line method, and rescue an expected class of errors.
Aside from testing failure, this isolation makes our other tests easier. We can stub the fetch_tweets method and forget about the interface to the Twitter library.
HTTP_ERRORS comes from the Suspenders’ errors initializer and Twitter::Search::ERRORS is something custom that we’re experimenting with in a real-world app, Thunder Thimble, that we’ll merge upstream to the Twitter gem when we feel we’ve learned enough.
We use Joe Ferris’ branch of Mocha for its test spies. We hope this Mocha mailing list thread will lead to merging the branch into Mocha. Please comment there if you have an opinion.
*(HTTP_ERRORS + Twitter::Search::ERRORS).each do |error|
should "notify hoptoad upon #{error} on fetch tweets" do
brand = Factory.build(:brand)
search = stub('search')
search.stubs(:fetch).raises(error.new(''))
HoptoadNotifier.stubs(:notify)
brand.fetch_tweets(search)
assert_received(HoptoadNotifier, :notify) do |expects|
expects.with(is_a(error))
end
end
end
This is a classic stub-and-spy test.
It uses the normal Four-Phase Test structure. The extra newlines separate the setup, exercise, and verification phases. The test is flat; it does not use a context block.
I’m happy with this approach. What do you think?