Threads and errors

What techniques are available for handling errors that occur in
threads?

For example how do I find out that an error occured in t below?

t = Thread.new { raise "error" }

I need to be able to check on the error status of threads from their
parent. Something like the following would be ideal - but I know this
won't do what I want:

begin
Thread.new { raise "error"}
rescue
puts $! # in a strange world prints "error", but in actuality does
nothing
end

-Charlie

Hi,

At Mon, 20 Dec 2004 09:02:12 +0900,
Charles Mills wrote in [ruby-talk:124052]:

What techniques are available for handling errors that occur in
threads?

Thread#join propagats the exception occurred in the thread to
the caller. Or, Thread#abort_on_exception flag directs to the
interpreter to abort.

For example how do I find out that an error occured in t below?

t = Thread.new { raise "error" }

  begin
    t.join
  rescue
    puts $!
  end

···

--
Nobu Nakada

Charles Mills wrote:

What techniques are available for handling errors that occur in
threads?

For example how do I find out that an error occured in t below?

t = Thread.new { raise "error" }

I need to be able to check on the error status of threads from their
parent. Something like the following would be ideal - but I know this
won't do what I want:

begin
Thread.new { raise "error"}
rescue
puts $! # in a strange world prints "error", but in actuality does
nothing
end

Another approach:

   begin
     Thread.new(Thread.current) do |th|
       begin
         raise "error"
       rescue => e
         th.raise e
       end
     end
   rescue => e
     p e
   end

"Charles Mills" <cmills@freeshell.org> schrieb im Newsbeitrag
news:1103500878.714949.188970@c13g2000cwb.googlegroups.com...

What techniques are available for handling errors that occur in
threads?

For example how do I find out that an error occured in t below?

t = Thread.new { raise "error" }

I need to be able to check on the error status of threads from their
parent. Something like the following would be ideal - but I know this
won't do what I want:

begin
Thread.new { raise "error"}
rescue
puts $! # in a strange world prints "error", but in actuality does
nothing
end

Apart from the other proposed solutions you can catch the exception at the
main level of the thread (Test 0) or you can use
"Thread.abort_on_exception = true" (Test 1 and 2):

10:20:08 [ruby]: ruby thread-abort-test.rb
#<RuntimeError: Test 0>
thread-abort-test.rb:2
thread-abort-test.rb:4
thread-abort-test.rb:6
thread-abort-test.rb:7: Test 2 (RuntimeError)
        from thread-abort-test.rb:7:in `initialize'
        from thread-abort-test.rb:7:in `new'
        from thread-abort-test.rb:7
10:20:19 [ruby]: cat thread-abort-test.rb
Thread.new { begin; raise "Test 0"; rescue Exception => e; p e; end }
puts "#{__FILE__}:#{__LINE__}"
Thread.new { raise "Test 1" }
puts "#{__FILE__}:#{__LINE__}"
Thread.abort_on_exception = true
puts "#{__FILE__}:#{__LINE__}"
Thread.new { raise "Test 2" }
puts "#{__FILE__}:#{__LINE__}"

Kind regards

    robert

Hi,

At Mon, 20 Dec 2004 15:45:10 +0900,
Joel VanderWerf wrote in [ruby-talk:124079]:

Another approach:

   begin
     Thread.new(Thread.current) do |th|
       begin
         raise "error"
       rescue => e
         th.raise e
       end
     end
   rescue => e
     p e
   end

It's not predictable when the parent thread will be
interrupted. It may be after the rescue block.

···

--
Nobu Nakada

Joel VanderWerf wrote:

Charles Mills wrote:
> What techniques are available for handling errors that occur in
> threads?
>
> For example how do I find out that an error occured in t below?
>
> t = Thread.new { raise "error" }
>
> I need to be able to check on the error status of threads from

their

> parent. Something like the following would be ideal - but I know

this

> won't do what I want:
>
> begin
> Thread.new { raise "error"}
> rescue
> puts $! # in a strange world prints "error", but in actuality does
> nothing
> end

Another approach:

   begin
     Thread.new(Thread.current) do |th|
       begin
         raise "error"
       rescue => e
         th.raise e
       end
     end
   rescue => e
     p e
   end

Perfect, that is exactly what I was looking for. Basically my
situation is as follows:

···

####
..begin
.. Thread.new(Thread.current) do |th|
.. # do some processing
.. begin
.. raise "error"
.. rescue => e
.. th.raise e
.. end
.. end
.. # also do some processing
..rescue => e
.. puts e
..end
#### ignore leading dots - google groups seems to strip leading
whitespace :-/

Two threads asyncronously doing some processing, the child thread needs
to be able to notify the parent if errors occur during the processing
(rarely happens). The details are explained here:
http://rubyforge.org/pipermail/dnssd-developers/2004-December/000000.html
Thanks,
Charlie

#### tmp.rb s/^\.//
..begin
.. Thread.new(Thread.current) do |th|
.. sleep 1
.. begin
.. raise "error"
.. rescue => e
.. th.raise e
.. end
.. end
..rescue => e
.. puts e
..end

..puts "before sleep"
..sleep 2
..puts "after sleep"

···

nobu.nokada@softhome.net wrote:

Hi,

At Mon, 20 Dec 2004 15:45:10 +0900,
Joel VanderWerf wrote in [ruby-talk:124079]:
> Another approach:
>
> begin
> Thread.new(Thread.current) do |th|
> begin
> raise "error"
> rescue => e
> th.raise e
> end
> end
> rescue => e
> p e
> end

It's not predictable when the parent thread will be
interrupted. It may be after the rescue block.

####
$ ruby tmp.rb
before sleep
tmp.rb:5: error (RuntimeError)
from tmp.rb:2:in `initialize'
from tmp.rb:2:in `new'
from tmp.rb:2
## If you comment out the 'sleep 1' line you get a much different
result: ##
$ ruby tmp.rb
error
before sleep
after sleep

Depending on the situation it may be necessary to keep the rest of the
code the begin/rescue block.

-Charlie