26

他の例外と同様に、遅延ジョブで例外が発生したときに ExceptionNotifier にメールを送信してもらいたいです。どうすればそれを達成できますか?

4

6 に答える 6

23

Rails 3.2.6、delayed_job 3.0.3、およびexception_notification 2.6.1 gemでこれを行います

# In config/environments/production.rb or config/initializers/delayed_job.rb

# Optional but recommended for less future surprises.
# Fail at startup if method does not exist instead of later in a background job 
[[ExceptionNotifier::Notifier, :background_exception_notification]].each do |object, method_name|
  raise NoMethodError, "undefined method `#{method_name}' for #{object.inspect}" unless object.respond_to?(method_name, true)
end

# Chain delayed job's handle_failed_job method to do exception notification
Delayed::Worker.class_eval do 
  def handle_failed_job_with_notification(job, error)
    handle_failed_job_without_notification(job, error)
    # only actually send mail in production
    if Rails.env.production?
      # rescue if ExceptionNotifier fails for some reason
      begin
        ExceptionNotifier::Notifier.background_exception_notification(error)
      rescue Exception => e
        Rails.logger.error "ExceptionNotifier failed: #{e.class.name}: #{e.message}"
        e.backtrace.each do |f|
          Rails.logger.error "  #{f}"
        end
        Rails.logger.flush
      end
    end
  end 
  alias_method_chain :handle_failed_job, :notification 
end

このコードをすべての環境にロードして、バンドルの更新後などにエラーが本番環境に到達する前にキャッチすることをお勧めします。ファイルを用意してこれを行いconfig/initializers/delayed_job.rbますが、環境ごとにコードを複製できconfig/environments/*ます。

もう 1 つのヒントは、遅延ジョブの構成を少し調整することです。デフォルトでは、ジョブが失敗したときに多くの重複した例外メールを受け取る可能性があります。

# In config/initializers/delayed_job_config.rb
Delayed::Worker.max_attempts = 3

更新デーモンがサイレントに終了するという問題がいくつかありましたが、メールの送信に失敗し、誰も例外を救出できなかったdelayed_jobことが判明しました。ExceptionNotifierこれで、コードがレスキューしてログに記録します。

于 2011-08-06T15:43:17.520 に答える
6

@MattiasWadman の回答に追加すると、 exception_notification 4.0 以降、manual notify を処理する新しい方法があります。したがって、代わりに:

ExceptionNotifier::Notifier.background_exception_notification(error)

使用する

ExceptionNotifier.notify_exception(error)
于 2013-12-09T18:55:44.003 に答える
4

例外を処理する別の方法 (イニシャライザとして配置):

class DelayedErrorHandler < Delayed::Plugin

  callbacks do |lifecycle|

    lifecycle.around(:invoke_job) do |job, *args, &block|

      begin
        block.call(job, *args)
      rescue Exception => e

        # ...Process exception here...

        raise e
      end
    end
  end
end

Delayed::Worker.plugins << DelayedErrorHandler
于 2015-08-25T18:46:28.170 に答える
2

exception_notification 3.0.0 の変更の場合:

ExceptionNotifier::Notifier.background_exception_notification(error)

に:

ExceptionNotifier::Notifier.background_exception_notification(error).deliver
于 2013-01-08T18:07:32.713 に答える