fxRuby and errors

Hi,

I just started to make my first ‘real’ application using Ruby and
fxRuby as a GUI.

I’ve noticed that if I kill my application using Ctrl-C instead of
killing it through the windowmanager, I don’t get any errors raised.

My application runs in a thread separate from the GUI thread, as shown
here:

···

—===—

application = FXApp.new(‘Foo’)

window = Window.new(application)

application.create

thread = Thread.new {
runTrueApplication
}

application.run

thread.join

===—===

If ‘runTrueApplication’ raises something I’d think would be considered
a ‘fatal’ error, namely that it tries to call a method that doesn’t
exist (raises NoSuchMethod, IIRC) I don’t get to know about that
error. Only after I kill the application by closing the window I get
the error message printed to stderr. Interrupting the process with
Ctrl-C just kills the program and nothing gets printed out.

This leads me to think that I’ve missed something important about how
Threads and Exceptions play together. Could someone please straight
this out for me? I guess thread.join is the key? It collects all
thrown exceptions? Is there a way for me to know about thrown errors
/before/ thread.join? Apart from;
[…]
thread = Thread.new {
begin
runTrueApplication
rescue
puts "Something happened that you should know about: #{$!}"
end
}

TIA,
//F, switches between {} and begin/end all the time. :wink:

Fredrik Jagenheim wrote:

If ‘runTrueApplication’ raises something I’d think would be considered
a ‘fatal’ error, namely that it tries to call a method that doesn’t
exist (raises NoSuchMethod, IIRC) I don’t get to know about that
error. Only after I kill the application by closing the window I get
the error message printed to stderr. Interrupting the process with
Ctrl-C just kills the program and nothing gets printed out.

This leads me to think that I’ve missed something important about how
Threads and Exceptions play together. Could someone please straight
this out for me? I guess thread.join is the key? It collects all
thrown exceptions? Is there a way for me to know about thrown errors
/before/ thread.join? Apart from;

See if this helps:

Thread.abort_on_exception = true

(assign this at the start of your code). Otherwise, threads other than
the main thread die silently.

Or you could catch exceptions in your thread itself.

Yes, that worked perfectly. Thanks.

But it brought me no closer to understanding what really happened to
the thread that threw the exception.

Setting abort_on_exception to true indicates that it doesn’t /abort/
when you get an exception by default, and you say it ‘dies silently’.

So, correct me if I’m wrong, the thread dies, and lies dormant until
reaped by Tread.join? Actually, when I typed that I think I understand
what really happened. When the thread died due to the exception, it
was suspended. When join was called, the thread was ‘promoted’ to the
main thread with an uncatched exception. And since the main thread
always abort on uncatched exceptions, we get a ‘verbose’ abort.

Or did I get it wrong?

//F

···

On Mon, Aug 25, 2003 at 05:28:00AM +0900, Joel VanderWerf wrote:

See if this helps:

Thread.abort_on_exception = true

(assign this at the start of your code). Otherwise, threads other than
the main thread die silently.

Fredrik Jagenheim wrote:

See if this helps:

Thread.abort_on_exception = true

(assign this at the start of your code). Otherwise, threads other than
the main thread die silently.

Yes, that worked perfectly. Thanks.

But it brought me no closer to understanding what really happened to
the thread that threw the exception.

Setting abort_on_exception to true indicates that it doesn’t /abort/
when you get an exception by default, and you say it ‘dies silently’.

So, correct me if I’m wrong, the thread dies, and lies dormant until
reaped by Tread.join? Actually, when I typed that I think I understand
what really happened. When the thread died due to the exception, it
was suspended. When join was called, the thread was ‘promoted’ to the
main thread with an uncatched exception. And since the main thread
always abort on uncatched exceptions, we get a ‘verbose’ abort.

I’m not really sure either, but your explanation makes sense, and here’s
what irb says:

irb(main):001:0> t = Thread.new { raise}
=> #<Thread:0x401f3e60 dead>
irb(main):002:0> Thread.list
=> [#<Thread:0x401d0d08 run>]
irb(main):003:0> t.join
RuntimeError:
from (irb):1
from (irb):3:in `join’
from (irb):3
irb(main):004:0> begin; t.join; rescue Exception; puts “CAUGHT!”; end
CAUGHT!
=> nil

So apparently the thread is ‘dead’, which is probably not the same thing
as suspended. But a dead thread can still be joined and you can catch
its exception (more than once, it seems). Hm, that’s good to know.

···

On Mon, Aug 25, 2003 at 05:28:00AM +0900, Joel VanderWerf wrote: