Skip to content

Instantly share code, notes, and snippets.

@myronmarston
Created July 28, 2012 22:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save myronmarston/3194995 to your computer and use it in GitHub Desktop.
Save myronmarston/3194995 to your computer and use it in GitHub Desktop.
Demonstration of changing the behavior of ruby's `rescue` so that it only handles shallow exceptions raised in directly called methods. Note that a bare `rescue` won't work with this, unfortunately. See https://twitter.com/garybernhardt/status/229323716
$ ruby --version
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.4.0]
$ ruby shallow_exceptions.rb
Exception handled: shallow exception
shallow_exceptions.rb:13:in `raise_shallow_exception': deep exception (StandardError)
from shallow_exceptions.rb:17:in `raise_deep_exception'
from shallow_exceptions.rb:27:in `try_handle_deep_exception'
from shallow_exceptions.rb:34:in `<main>'
def Exception.===(exception)
# verify the main part of the backtrace matches...
return false unless (exception.backtrace[1..-1] == caller[1..-1])
# verify the rescue is in the same method as the caller of the method that raised.
caller_of_method_that_raised = exception.backtrace[1][/:\d+:in `([^']+)'\z/, 1]
rescuer = caller[0][/:\d+:in `(?:rescue in )?([^']+)'\z/, 1]
caller_of_method_that_raised == rescuer
end
def raise_shallow_exception(msg = "shallow exception")
raise StandardError, msg
end
def raise_deep_exception
raise_shallow_exception "deep exception"
end
def handle_shallow_exception
raise_shallow_exception
rescue StandardError => e
puts "Exception handled: #{e.message}"
end
def try_handle_deep_exception
raise_deep_exception
rescue StandardError => e
# this won't be triggered
puts "Exception handled: #{e.message}"
end
handle_shallow_exception
try_handle_deep_exception
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment