From: Brian Candler on
Martin Hansen wrote:
> Now, I would like error handling to be invoked, if possible from
> biopieces.rb, in the case some exception is raised (either by raise or
> ctrl-c, etc)

What do you want the exception handler to do? Will the program still
terminate afterwards?

If so, why not just add an at_exit handler?

--- prog1.rb ---
at_exit { puts "Last exception was #{$!.inspect}" if $! }
raise "Boom"

--- prog2.rb ---
at_exit { puts "Last exception was #{$!.inspect}" if $! }
puts "Nothing happened"

--- prog3.rb ---
at_exit { puts "Last exception was #{$!.inspect}" if $! }
begin
raise "Caught it"
rescue RuntimeError
end
puts "Nothing happened"

--- prog4.rb ---
at_exit { puts "Last exception was #{$!.inspect}" if $! }
begin
raise "Caught it"
rescue RuntimeError
end
sleep 10
puts "Nothing happened"

Note that both prog2 and prog3 terminate successfully and don't report
any exception. prog4 reports Interrupt if you terminate with ^C.

Your at_exit code can of course sit in a separate source file that you
require.
--
Posted via http://www.ruby-forum.com/.

From: Martin Hansen on
> What do you want the exception handler to do? Will the program still
> terminate afterwards?

I want to write the exception type to a log file and terminate the
script. $! does not tell the difference between interrupt, terminate,
and quit (perhaps that could be fixed? - just a thought).

> If so, why not just add an at_exit handler?

I have been messing around with this for a while, but I have failed to
get it right - and now I am utterly confused.

If I have test.rb:

#!/usr/bin/env ruby

require 'my_aux_class'

Greet.new

raise "raise from main"


And my_aux_class.rb:

class Greet
def initialize
puts "Hello World"
end
end

at_exit {
puts "Last exception was #{$!.inspect}" if $!
}

begin
exit_status = "OK"

%w( INT TERM QUIT ).each do |signal|
Signal.trap(signal) do
exit_status = signal
exit
end
end

raise "raise from aux"
rescue Exception => exception
puts "rescuing #{exception}"
puts exception.backtrace
ensure
puts "exit status: #{exit_status}"
end

Running this I get the following output:

rescuing raise from aux
/Users/maasha/my_aux_class.rb:21:in `<top (required)>'
/test.rb:3:in `require'
/test.rb:3:in `<main>'
exit status: OK
Hello World
Last exception was #<RuntimeError: raise from main>
/test.rb:7:in `<main>': raise from main (RuntimeError)


I actually wanted the raise from main rescued, but the
begin/rescue/ensure is misplaced/misused :o(



Martin

--
Posted via http://www.ruby-forum.com/.

From: Brian Candler on
Martin Hansen wrote:
> $! does not tell the difference between interrupt, terminate,
> and quit (perhaps that could be fixed? - just a thought).

It does for me.

$ cat ert.rb
at_exit { puts "Last exception was #{$!.inspect}" if $!; exit! }
sleep 100
puts "Nothing happened"

### Ctrl-C:
$ ruby ert.rb
^CLast exception was Interrupt
ert.rb:2:in `sleep': Interrupt
from ert.rb:2

### kill -TERM (from another window):
$ ruby ert.rb
Last exception was #<SignalException: SIGTERM>
Terminated

### kill -QUIT:
Last exception was #<SignalException: SIGQUIT>
Quit

This is with ruby 1.8.7 (2010-01-10 patchlevel 249) [x86_64-linux] under
Ubuntu Lucid amd64.

So I don't understand why you're trying to trap all of these signals,
when they all cause the program to terminate, and they can all be
distinguished in $!. But perhaps your platform behaves differently?

Final note: inside your at_exit handler, you can use 'exit!' to prevent
any further processing, i.e. the default output of the backtrace or
signal.
--
Posted via http://www.ruby-forum.com/.

From: Brian Candler on
> at_exit { puts "Last exception was #{$!.inspect}" if $!; exit! }

Actually, the sample output I showed was without the 'exit!'

--
Posted via http://www.ruby-forum.com/.

From: Martin Hansen on
This works great! I was sure I had tested this, but I had screwed up the
test somehow - perhaps trap changed something. Anyways - this will work!

Thanks a zillion for the patient assistance!


Martin
--
Posted via http://www.ruby-forum.com/.