Catching Exceptions Across Suite

93 views
Skip to first unread message

Dylan Reichstadt

unread,
Jul 22, 2015, 9:10:16 PM7/22/15
to rspec
Hey All,

I am looking to add better instrumentation around exceptions thrown in rspec. For example, I want to track how many times I get a Net::ReadTimeout error from Capybara/Rspec.

In a limited scope, I have been:
  • Rescuing this exception
  • Incrementing a global variable
  • Re-raising that exception again (after incrementing)

However, this exception can happen across all examples. I don't want to wrap every scenario in a Begin & Rescue block - that sounds extremely messy.

Does rspec have something to help with this, or does anyone have any ideas I can achieve better tracking of exceptions? I have been googling around RSpec and Catching All Exceptions, but can't find anything.

Jon Rowe

unread,
Jul 22, 2015, 9:11:44 PM7/22/15
to rs...@googlegroups.com
Not specifically, but you can configure an around hook to do what you want:

Rspec.configure do |config|
  config.around(:example) do |example|
    begin
      example.run
    rescue Net::ReadTimeout
      # … your code
      raise
    end
  end
end

Jon Rowe
---------------------------

--
You received this message because you are subscribed to the Google Groups "rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rspec+un...@googlegroups.com.
To post to this group, send email to rs...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rspec/88d51b4d-2bb3-4391-bffd-476663474a07%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dylan Reichstadt

unread,
Jul 22, 2015, 10:20:11 PM7/22/15
to rspec, ma...@jonrowe.co.uk
Hey Jon,

Pretty solid idea! I didn't think of this.

Unfortunately it doesn't look to catch the exception though. Tested with RSpec::Expectations::ExpectationNotMetError

This was a snippet of my code (which never printed 'In here!' when the exception was raised - I tried simply rescue Exception as well):

RSpec.configure do |config|
  config
.around(:each) do |example|
   
begin
      example
.run
   
rescue RSpec::Expectations::ExpectationNotMetError
      puts
'In here!'
     
raise
   
end
 
end
end

Myron Marston

unread,
Jul 22, 2015, 10:29:47 PM7/22/15
to rs...@googlegroups.com, Jon Rowe

Rescuing exceptions in an around hook won’t work because within example.run RSpec rescues the exception as part of tracking the example state, notifying formatters, etc.

Are you looking to track all raised exceptions (even if something rescues them and/or retries)? Or just all the example failure exceptions?

If you’re looking for the former, you’ll probably have to monkey patch Kernel#raise or use a tracepoint.

If you’re looking for the latter, you can implement a listener/formatter that registers the :example_failed event with RSpec so that it is notified every time an example fails, and then you can do whatever you want when notified.

HTH,
Myron


Dylan Reichstadt

unread,
Aug 3, 2015, 7:33:25 PM8/3/15
to rspec, ma...@jonrowe.co.uk
Thanks, Myron!

I went about implementing the tracking within a formatter. Looks to be working great.

Will probably shortly refactor to remove the use of the global variable, but here's a snippet of code for any future onlookers:

require 'rspec/core/formatters/base_formatter'

$read_timeout_count = 0 # Used to track Net::ReadTimeout Exceptions

module RSpec
  module Stats
    class Formatter < RSpec::Core::Formatters::BaseFormatter

      def example_failed(notification)
        if notification.exception.to_s.include?('Net::ReadTimeout')
          $read_timeout_count += 1
        end
      end

    end
  end
end

Within dump_summary, I then gauge $read_timeout_count to Statsd.
Reply all
Reply to author
Forward
0 new messages