From: Joel VanderWerf Date: 2003-11-29T08:53:40+09:00 Subject: Re: re-raising an exception with the original backtrace David A. Black wrote: > Hi -- > > On Sat, 29 Nov 2003, Joel VanderWerf wrote: > > >>Is there a way to re-raise an exception without replacing its backtrace >>with the current one? >> >>The reason I want to do this is that I am catching an exception and >>passing it to a handler. The handler needs to make a decision and then, >>possibly, re-raise the same exception, preferrably with the same >>information as it originally contained. >> >>But if I do the following, the exception takes on the backtrace of the >>handler, which has lost some information. I know I can add the original >>backtrace to the exception's message, but that's not the same thing... >> >>$ cat exception.rb >> >> class MyError < StandardError; end >> >> def foo >> raise MyError >> end >> >> def main >> foo >> rescue Exception => e >> handler(e) >> end >> >> def handler(e) >> ok = false >> if ok >> return true >> else >> puts "backtrace:", e.backtrace, "---" >> raise e > > > I think if you just do 'raise' there, instead of 'raise e', it will > propagate the original exception and backtrace. Ooh, that's nice. I thought 'raise' would just re-raise the _last_ exception, but it's actually sensitive to the dynamic context. The example below would fail in the former case, but since it succeeds, I guess raise looks back down the stack and re-raises the first exception it finds there? $ cat exception.rb class MyError < StandardError; end def foo raise MyError end def main foo rescue Exception => e handler(e) end class OtherError < StandardError; end def do_something_that_might_use_exceptions raise OtherError rescue Exception => e p e false end def handler(e) ok = do_something_that_might_use_exceptions if ok return true else puts "backtrace:", e.backtrace, "---" raise end end main $ ruby exception.rb # backtrace: exception.rb:4:in `foo' exception.rb:8:in `main' exception.rb:31 --- exception.rb:4:in `foo': MyError (MyError) from exception.rb:8:in `main' from exception.rb:31