Reputation: 24850
I am trying to code up a two-threads client using ruby, one thread reads the data from a socket and print it out, the other thread reads local data and send it to remote server. The problem I found is that it looks like Ruby cannot capture errors within a thread, here is an example:
#! /usr/bin/ruby
Thread.new {
loop {
$stdout.puts "hi"
abc.puts ef
sleep 1
}
}
loop {
sleep 1
}
Obviously, outside the thread if I type abc.puts ef
the code will never run since Ruby will report "undefined variable abc". However if it is within a thread, there is no error report. My question is, how to let Ruby capture errors like this? Or at least, report something is wrong within a thread?
Upvotes: 5
Views: 2214
Reputation: 433
For syntax error catching, rescue must use explict Exception class (without this, rescue catch only StandardError) :
Thread.new {
begin
abc.puts ef
rescue Exception => e
puts "error #{e}"
end
}
see Why can't `rescue` catch exception classes other than `StandardError` by default?
Upvotes: 3
Reputation: 369064
Use Thread::abort_on_exception=:
According to Thread - Exception Handling:
Any thread can raise an exception using the raise instance method, which operates similarly to Kernel#raise.
However, it's important to note that an exception that occurs in any thread except the main thread depends on abort_on_exception. This option is false by default, meaning that any unhandled exception will cause the thread to terminate silently when waited on by either join or value. You can change this default by either abort_on_exception= true or setting $DEBUG to true.
...
Thread::abort_on_exception = true
Thread.new {
loop {
$stdout.puts "hi"
abc.puts ef
sleep 1
}
}
loop {
sleep 1
}
=>
hi
t.rb:5:in `block (2 levels) in <main>': undefined local variable or method `abc' for main:Object (NameError)
from t.rb:3:in `loop'
from t.rb:3:in `block in <main>'
Upvotes: 6
Reputation: 24850
Ok, one possible solution is surround the thread lambda with begin
rescue
end
block:
Thread.new {
begin
abc.puts ef
rescue
puts error
end
}
Upvotes: 0