Techioz Blog

Rubyのグローバル例外ハンドラ

概要

Rubyで例外用のグローバルリスナーを作成することは可能ですか?

StateMachine::InvalidTransition のスクリプト内のすべての例外をキャッチして、アプリケーションがエラーを含む電子メールを送信して応答できるようにしたいと考えています。

通常、Ruby ではレスキュー ブロックの前に begin が置かれますが、上記の例外をすべてキャッチする中央のリスナー メソッドが必要です。

そもそもそんなことは可能なのでしょうか?

本当は置きたくない

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

state_machine にあるすべてのイベントの内部。

PHP の set_Exception_handler() に似たものが必要です。

解決策

はい、例外用のグローバル リスナーを作成できます。ここでは 2 つのアプローチを示します。

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

このアプローチは、スクリプトの終了を停止できないため、クラッシュロガーとしてのみ役立ちます。

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

この方法ではスクリプトの終了を停止できますが、他に 2 つの制限があります。