Catching thread exceptions

Recently I was helping a colleague who was new to Ruby with a program
that was using threads. It seemed to him that for some reason that some
of the thread’s were not running. First he tried adding sleeps to the
main thread to “give time” to the other threads to run, but this didn’t
work. It turns out that by joining the threads in question, that there
were errors in the program that were throwing exceptions that killed the
thread – SILENTLY.

I don’t know if there is a better way to do this, but this is the
solution we came up with to print out any exceptions that occur in a
thread (uncaught) and exit the program.

require “thread”

class MyThread < Thread
def initialize(*args, &block)
super(*args) do
begin
block.call
rescue Exception => e
$stderr.print “Exception occured: #{e.message} at " +
e.backtrace.join(”\n")
exit! 1
end
end
end
end

Is there a better way?

Steve Tuckner

Is there a better way?

Thread.abort_on_exception = true

svg% ruby -e 'Thread.new { raise "aa" }; p "after"'
"after"
svg%

svg% ruby -e 'Thread.abort_on_exception = true; Thread.new { raise "aa" }; p "after"'
-e:1: aa (RuntimeError)
        from -e:1:in `initialize'
        from -e:1:in `new'
        from -e:1
svg%

Guy Decoux

described at
http://www.rubycentral.com/book/tut_threads.html
and
http://www.rubycentral.com/book/ref_c_thread.html#Thread.abort_on_exception

Regards,

Brian.

···

On Sat, Aug 09, 2003 at 02:34:48AM +0900, ts wrote:

Is there a better way?

Thread.abort_on_exception = true

Why is false by default? In what case would you want an exception to
propagate to the top of a thread and kill it SILENTLY and then keep running?
Why doesn’t it at least print something out if it isn’t going to kill the
program?

We had a problem where a DRb server died silently causing a lot of headache
trying to figure out why the program was suddenly no longer functioning
correctly. Any module that a person imports that uses threads (unknown to
the user of that module) can die and cause problems SILENTLY.

With my change, the exception could always print out a message and die based
on an option like abort_on_exception.

Steve Tuckner

···

-----Original Message-----
From: ts [mailto:decoux@moulon.inra.fr]
Sent: Friday, August 08, 2003 12:35 PM
To: ruby-talk ML
Cc: ruby-talk@ruby-lang.org
Subject: Re: Catching thread exceptions

Is there a better way?

Thread.abort_on_exception = true

svg% ruby -e ‘Thread.new { raise “aa” }; p “after”’
“after”
svg%

svg% ruby -e ‘Thread.abort_on_exception = true; Thread.new {
raise “aa” }; p “after”’
-e:1: aa (RuntimeError)
from -e:1:in initialize' from -e:1:in new’
from -e:1
svg%

Guy Decoux

Although a little late I try to answer that one.

“Steve Tuckner” STUCKNER@MULTITECH.COM schrieb im Newsbeitrag
news:00ed01c35ddb$fe568590$6904a8c0@multitech.prv…

Why is false by default? In what case would you want an exception to
propagate to the top of a thread and kill it SILENTLY and then keep
running?

IMHO this is the setting that minimally affects stability of a program.
Imagine a server that spawns threads for requests. If any of those
threads dies due to some error you don’t want the whole server to stop.
The proper way to do it is IMHO to handle errors from within the thread:

Thread.new do
begin
raise “aa”
rescue => e
$stderr.puts “ERROR: #{e}”
else
$stdout.puts “fine”
end
end

Why doesn’t it at least print something out if it isn’t going to kill
the
program?

That’s another story and possibly a good suggestion: have ruby print a
message to STDERR if a thread terminates with an uncaught exception.

Regards

robert