From: Robert Klemme Date: 2011-01-26T02:27:55+09:00 Subject: Re: Does Ruby support exception wrapping (exception chaining)? On Tue, Jan 25, 2011 at 4:56 PM, Ryan Heneise wrote: > Robert Klemme wrote in post #977344: >> DRb really seems the only place where a kind of wrapping may make >> sense but even here you probably do not want to wrap exceptions but >> just carry over backtraces, because the exception class may not be >> known to the client. > > An example of where this can be infinitely useful is in parsing a CSV or > Excel file, or iterating over any collection of data. Often a tuple will > trigger an exception, and it's useful to know on which line the problem > occurred. > > tuples.each_with_index do |tuple, i| >  begin >    Something.create(tuple) >  rescue Exception => e >    raise $!, "#{$!} on row #{i}", $!.backtrace I'd rather use e instead of $! since we have it already: raise e, "#{e} on row #{i}", e.backtrace >  end > end > > This would give you an error like: > > "NoMethodError: undefined method `foobar' for nil:NilClass on row 123" > > ...which is very helpful when tracking down data processing errors. > > Notice that it still raises the original error, including the original > error class, and the original backtrace. Only the message has changed. In this case I would chose one of these two approaches: 1. output the original error along with meta data error_count = 0 # in case we need this information tuples.each_with_index do |tuple, i| begin Something.create(tuple) rescue Exception => e $stderr.puts "Error with processing tuple #{i}: #{tuple.inspect}", e.backtrace error_count += 1 end end 2. Create a custom error class that carries all information needed. class DataError < StandardError attr_reader :tuple, :meta_data, :source_error def initialize(tuple, meta_data = nil, source_error = $!) @tuple = tuple @meta_data = meta_data @source_error = source_error end end tuples.each_with_index do |tuple, i| begin Something.create(tuple) rescue Exception => e raise DataError.new(tuple, i, e), "Error with tuple #{i}" end end Whether I'd pick 1 or 2 would largely depend on the size of the application and whether I need structured handling of those errors. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/