How do I rescue a program exception in an at_exit block?

I was thinking about how bad I am at reading error messages, and realized
it could be useful to catch the exception and write it in a way that was
easier for me to find the relevant information. So, came up with this proof
of concept:

at_exit do
  error = $!
  if error
    pink, normal, red, green = "\e[35m", "\e[0m", "\e[31m", "\e[32m"

    puts
    puts "#{pink}#{error.class}"
    puts "#{red}#{error.message}#{normal}"
    puts
    puts error.backtrace.map { |line|
      line.sub(%r([^/:]*(?=:))) { |match| "#{green}#{match}#{normal}" }
          .sub(%r((?<=:)\d+(?=:))) { |match| "#{pink}#{match}#{normal}" }
    }
  end
end

The problem, though, is that $! is still set after this block runs, and so
Ruby still spits out its own exception message afterwards. I don't know how
to stop it from doing this.

I tried setting $!, but it's a read-only variable. Tried raising and
rescuing another exception, which cleared $! for the rest of that at_exit
block, but it was still around in the next at_exit block, and so Ruby still
printed it out. Not sure what else to try.

-Josh

It's a pure, unadulterated hack, but you can "exec" something at the
end of your at_exit block, to replace the ruby process with something
else, thus avoiding the final error report.

  at_exit do
    error = $!
    if error
      #...
    end
    exec 'echo -n ""'
  end
  raise 'badness'

···

On 6 July 2013 00:08, Josh Cheek <josh.cheek@gmail.com> wrote:

I was thinking about how bad I am at reading error messages, and realized it
could be useful to catch the exception and write it in a way that was easier
for me to find the relevant information. So, came up with this proof of
concept:

at_exit do
  error = $!
  if error
    pink, normal, red, green = "\e[35m", "\e[0m", "\e[31m", "\e[32m"

    puts
    puts "#{pink}#{error.class}"
    puts "#{red}#{error.message}#{normal}"
    puts
    puts error.backtrace.map { |line|
      line.sub(%r([^/:]*(?=:))) { |match| "#{green}#{match}#{normal}" }
          .sub(%r((?<=:)\d+(?=:))) { |match| "#{pink}#{match}#{normal}" }
    }
  end
end

The problem, though, is that $! is still set after this block runs, and so
Ruby still spits out its own exception message afterwards. I don't know how
to stop it from doing this.

I tried setting $!, but it's a read-only variable. Tried raising and
rescuing another exception, which cleared $! for the rest of that at_exit
block, but it was still around in the next at_exit block, and so Ruby still
printed it out. Not sure what else to try.

-Josh

--
  Matthew Kerwin, B.Sc (CompSci) (Hons)
  http://matthew.kerwin.net.au/

This won't help you, but I once ran into a problem with multiple at_exit
in different projects. Since I found no clean solution and they gave me
different trouble, I decided to stop using at_exit hook. Since that day
I am wondering if there is really a clear need for at_exit usage - when
I write gems, I never seem to really need it.

···

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

But why go through those hoops and do it in at_exit? You could simply put
"begin rescue end" around your main script.

Kind regards

robert

···

On Fri, Jul 5, 2013 at 4:08 PM, Josh Cheek <josh.cheek@gmail.com> wrote:

I was thinking about how bad I am at reading error messages, and realized
it could be useful to catch the exception and write it in a way that was
easier for me to find the relevant information. So, came up with this proof
of concept:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

If you call exit! in your at_exit block it will exit immediately and
prevent other at_exit blocks from running. That might prevent the default
message from being printed. You might also be able to wrap the rest of the
code in a begin; rescue SystemExit; end block instead. You may find this (
http://www.bigfastblog.com/ruby-exit-exit-systemexit-and-at_exit-blunder\)
article helpful, especially the comment mentioned at the end.

···

On Fri, Jul 5, 2013 at 11:33 AM, Marc Heiler <lists@ruby-forum.com> wrote:

This won't help you, but I once ran into a problem with multiple at_exit
in different projects. Since I found no clean solution and they gave me
different trouble, I decided to stop using at_exit hook. Since that day
I am wondering if there is really a clear need for at_exit usage - when
I write gems, I never seem to really need it.

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

I like the idea that I could just require a gem and have my error output
changed.

-Josh

···

On Sat, Jul 6, 2013 at 5:27 AM, Robert Klemme <shortcutter@googlemail.com>wrote:

On Fri, Jul 5, 2013 at 4:08 PM, Josh Cheek <josh.cheek@gmail.com> wrote:

I was thinking about how bad I am at reading error messages, and realized
it could be useful to catch the exception and write it in a way that was
easier for me to find the relevant information. So, came up with this proof
of concept:

But why go through those hoops and do it in at_exit? You could simply put
"begin rescue end" around your main script.

Also, some cases it's not clear how to do this. Say I wanted to put it in a
Rails app, that I run with the shotgun gem. The main script is in code I
don't control.

-Josh

···

On Sat, Jul 6, 2013 at 8:32 AM, Josh Cheek <josh.cheek@gmail.com> wrote:

On Sat, Jul 6, 2013 at 5:27 AM, Robert Klemme <shortcutter@googlemail.com>wrote:

On Fri, Jul 5, 2013 at 4:08 PM, Josh Cheek <josh.cheek@gmail.com> wrote:

I was thinking about how bad I am at reading error messages, and
realized it could be useful to catch the exception and write it in a way
that was easier for me to find the relevant information. So, came up with
this proof of concept:

But why go through those hoops and do it in at_exit? You could simply
put "begin rescue end" around your main script.

I like the idea that I could just require a gem and have my error output
changed.