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’

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.

On Fri, Jul 5, 2013 at 4:08 PM, Josh C. [email protected] 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.

Kind regards

robert

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
(
Ruby exit, exit!, SystemExit and at_exit blunder - Big Fast Blog)
article helpful, especially the comment mentioned at the end.

On Sat, Jul 6, 2013 at 5:27 AM, Robert K.
[email protected]wrote:

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.

-Josh

On Sat, Jul 6, 2013 at 8:32 AM, Josh C. [email protected] wrote:

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.

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