From: Yohanes Santoso Date: 2005-10-26T01:40:17+09:00 Subject: Re: Nested Exception Jacob Fugal writes: > On 10/25/05, Yohanes Santoso wrote: >> Would you accept a patch to provide nested Exception? >> >> def remove_user(name) >> begin >> File.unlink('something') >> more_exception_throwing_method_calls >> rescue >> raise UserManagementFailure.new("unable to remove user #{name}", $!) >> end >> end > > Doesn't this already work? Example: > > def example > begin > raise "Random error" > rescue > raise "Example failed" > end > end > > begin > example > rescue Exception => e > puts e > end > > The output I get is "Example failed". At this point, you lost the original 'Random error' exception. The idea is to attach a causing exception to a domain-specific exception for logging/auditing purposes. In my example above, the domain-specific exception, UserManagementFailure would contain the causing exception, say, and Errno::NOENT exception. This way, when logging exceptions, you can provide some contextual information: begin ... ... remove_user('foobar') rescue UserManagementFailure log($!) rescue .... end The logger could extract the causing exception to produce, for example: Exception: UserManagementFailure: unable to remove user foobar ... (some back trace to the "raise UserManagementFailure.new...." here) ... caused by: Errno::NOENT: no file named 'something' exists ... (some back trace to the "File.unlink('something')"... here) .... So, the patch would add an optional argument to Exception#initialisation(msg, cause=nil) and Exception.exception(msg, cause=nil), and a new method: Exception#cause which returns cause. YS.