Ilya Cherevkov
Ilya Cherevkov

Reputation: 1793

Log exact exception origin and its backtrace at_exit in Ruby

I want to always log as much information as possible about exception that caused multithreaded ruby script's crash. I know there is at exit method and that the latest error is accessible in $!

require 'logger'
logger = Logger.new('logfile.log')
at_exit { logger.info "Exception that killed us is: #{$!}" }

threads =
  10.times.with_object([]) do |_, t|
    t << Thread.new { sleep 1 }
  end

threads << Thread.new { raise RuntimeError, 'We died' }
threads.each(&:join)

However, in log this looks like:

I, [2018-08-23T10:40:47.307841 #6772]  INFO -- : Exception that killed us is: We died

Is there a way to add more information, like backtrace, file and line number to this?

Upvotes: 0

Views: 266

Answers (2)

Surya
Surya

Reputation: 15992

You can also use English based names for these exception messages:

require 'logger'
logger = Logger.new('logfile.log')
at_exit { logger.info "Exception that killed us is: #{$ERROR_INFO} - #{$ERROR_INFO.class} - #{$ERROR_POSITION}" }

threads =
  10.times.with_object([]) do |_, t|
    t << Thread.new { sleep 1 }
  end

threads << Thread.new { raise RuntimeError, 'We died' }
threads.each(&:join)

Keeping in mind that $ERROR_INFO will get you the exception message when provided else the exception class itself. while $ERROR_INFO.class gets you the exception class. In your case $ERROR_INFO will result in 'We died'.

Upvotes: 1

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 120990

Backtrace already contains file and lineno, $@ global contains a backtrace.

Upvotes: 2

Related Questions