urieljuliatti
urieljuliatti

Reputation: 35

Handle Errors with Delayed Job

Isn't there the possibility to handle errors with delayed_job gem? I would like to find a way (runtime) to send an email to a given account while the errors occur and after it performs delete them.

Upvotes: 2

Views: 4277

Answers (3)

knagode
knagode

Reputation: 6125

Not that code above doesn't report all the problems .. We recently got a lot issues on worker dynos and we were not even aware about them because we were listening for errors only ...

DelayedJob knows 2 type of errors - errors and failures. In our case - failures were triggered on lower level because we were using Octopus gem. Failure message was: undefined method[]' for nil:NilClass`

class DelayedJobExceptionPlugin < Delayed::Plugin
  def self.report_error(exception, job, type: 'error')
    Airbrake.notify(
      exception, 
      error_message: "#{exception.class.name}: #{exception.message}",
      backtrace: exception.backtrace,
      component: 'DelayedJob Worker',
      type: type,
      parameters: {
        failed_job: job.inspect
      },
    )
  end

  callbacks do |lifecycle|
    lifecycle.around(:invoke_job) do |job, *args, &block|
      begin
        # Forward the call to the next callback in the callback chain
        block.call(job, *args)
      rescue Exception => exception
        DelayedJobExceptionPlugin.report_error(exception, job)

        raise error
      end
    end

    lifecycle.after(:failure) do |job| # Note - some jobs did not trigger Airbrake.notify if we do not use failure!
      exception = ::RuntimeError.new('DelayedJob Failure')
      DelayedJobExceptionPlugin.report_error(exception, job, type: 'failure')

      raise exception if Rails.env.test?
    end
  end
end

Delayed::Worker.plugins << DelayedJobExceptionPlugin

Upvotes: 0

Augustin Riedinger
Augustin Riedinger

Reputation: 22148

Found the solution here : http://blog.salsify.com/engineering/delayed-jobs-callbacks-and-hooks-in-rails

# config/initizalizers/delayed_job.rb

class ExceptionMailerPlugin < Delayed::Plugin

  callbacks do |lifecycle|
    lifecycle.around(:invoke_job) do |job, *args, &block|
      begin
        # Forward the call to the next callback in the callback chain
        block.call(job, *args)
      rescue Exception => error
        ErrorMailer.exception_mail(error)
        # Make sure we propagate the failure!
        raise error
      end
    end
  end

end


Delayed::Worker.plugins << ExceptionMailerPlugin

Upvotes: 1

emrass
emrass

Reputation: 6444

Is this what you want?

def do_something
  # some code here
  begin
    # something that could go wrong here
  rescue Exception => e
    YourMailer.delay.your_method(e.to_s)
    # don't know what you want to delete, but you can do it here
  end
end

Upvotes: 1

Related Questions