Created
July 28, 2012 22:16
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ 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>' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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