Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global exception handler in Ruby

Tags:

ruby

Is it possible to create a global listener for an exception in Ruby?

I want to catch all exceptions in my script for StateMachine::InvalidTransition so my application can respond with sending an email with the error.

Normally in Ruby, a rescue block is preceded by begin, but I want to have a central listener method that will catch all exceptions for the above mentioned exception.

Is this possible at all?

I really don't want to place

begin
    # Do some stuff
rescue StateMachine::InvalidTransition => exception
    # Send error in email message
end 

inside every single event I have in my state_machine.

I want something similar to set_exception_handler() in PHP.

like image 826
josef.van.niekerk Avatar asked Jul 03 '26 10:07

josef.van.niekerk


1 Answers

Yes, it's possible to create a global listener for an exception. Here are two approaches:

1. at_exit and $!:

at_exit do
  if $!.is_a? StateMachine::InvalidTransition
    # Send error in email message
  end
end

This approach is only useful as a crash-logger, since it can't stop your script from exiting.

2. Patch raise and fail:

module PatchRaise
  def raise(err, *args)
    if defined?(err.exception) &&
      err.exception.is_a?(StateMachine::InvalidTransition)
      # Send error in email message
    else
      super(err, *args)
    end
  end

  def fail(*args)
    raise(*args)
  end
end

Object.prepend PatchRaise

This approach can stop your script from exiting, but it has two other limitations:

  • It will capture all calls to raise / fail, even ones that might otherwise be caught by a begin / rescue block elsewhere in your script.
  • Since it depends on overriding the Ruby raise and fail methods, will not catch any exceptions generated by native Ruby-core code or C extensions (e.g., ZeroDivisionError raised by the 1/0 expression).
like image 109
wjordan Avatar answered Jul 04 '26 22:07

wjordan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!