From: Alex Young Date: 2012-06-26T17:59:50+09:00 Subject: [ruby-core:45881] Re: [ruby-trunk - Bug #6647] Exceptions raised in threads should be logged On 25/06/12 23:44, rue (Eero Saynatkari) wrote: > > Issue #6647 has been updated by rue (Eero Saynatkari). > > > headius (Charles Nutter) wrote: >> Many applications and users I have dealt with have run into bugs due to Ruby's behavior of quietly swallowing exceptions raised in threads. I believe this is a bug, and threads should always at least log exceptions that bubble all the way out and terminate them. > > I have had to set .abort_on_exception more times than I care to remember. Agreed. It's one of the things I check for in code review. Consider this a +1 from me. > >> rescue Exception => e >> raise if Thread.abort_on_exception || Thread.current.abort_on_exception >> puts "Thread for block #{block.inspect} terminated with exception: #{e.message}" >> puts e.backtrace.map {|line| " #{line}"} > > $stderr/warn, but this would improve the current situation significantly. > > Can significant upgrade problems be expected if .abort_on_exception defaulted to true? This would seem to be the behaviour to suit most users. That sounds a little extreme, although I wouldn't object. I'd be happy with them not being silently swallowed. -- Alex > ---------------------------------------- > Bug #6647: Exceptions raised in threads should be logged > https://bugs.ruby-lang.org/issues/6647#change-27456 > > Author: headius (Charles Nutter) > Status: Open > Priority: Normal > Assignee: > Category: > Target version: > ruby -v: head > > > Many applications and users I have dealt with have run into bugs due to Ruby's behavior of quietly swallowing exceptions raised in threads. I believe this is a bug, and threads should always at least log exceptions that bubble all the way out and terminate them. > > The implementation should be simple, but I'm not yet familiar enough with the MRI codebase to provide a patch. The exception logging should be logged in the same way top-level exceptions get logged, but perhaps with information about the thread that was terminated because of the exception. > > Here is a monkey patch that simulates what I'm hoping to achieve with this bug: > > > class<< Thread > alias old_new new > > def new(*args,&block) > old_new(*args) do |*bargs| > begin > block.call(*bargs) > rescue Exception => e > raise if Thread.abort_on_exception || Thread.current.abort_on_exception > puts "Thread for block #{block.inspect} terminated with exception: #{e.message}" > puts e.backtrace.map {|line| " #{line}"} > end > end > end > end > > Thread.new { 1 / 0 }.join > puts "After thread" > > __END__ > > Output: > > system ~/projects/jruby $ ruby thread_error.rb > Thread for block # terminated with exception: divided by 0 > thread_error.rb:17:in `/' > thread_error.rb:17 > thread_error.rb:7:in `call' > thread_error.rb:7:in `new' > thread_error.rb:5:in `initialize' > thread_error.rb:5:in `old_new' > thread_error.rb:5:in `new' > thread_error.rb:17 > After thread > > >