Skip to content

Instantly share code, notes, and snippets.

@jackkinsella
Created May 16, 2014 14:13
Show Gist options
  • Save jackkinsella/842395841a0fff204e35 to your computer and use it in GitHub Desktop.
Save jackkinsella/842395841a0fff204e35 to your computer and use it in GitHub Desktop.
Delayed Job Background Notification modification
# copy to: config/initializers/delayed_job_config.rb
# 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
failing_method = job.handler.scan(/method_name: .*/).try(:first)
failing_db_object = job.handler.scan(/(?:id: )(.*)/).try(:first).try(:first)
ExceptionNotifier::Notifier.background_exception_notification(error, data: {failing_method: failing_method,
first_failing_db_object: failing_db_object,
job: job, handler: job.handler, last_error: job.last_error}).deliver
rescue Exception => e
# this means we can debug by referring to the logs and searching for "ExceptionNotifier"
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
Delayed::Job.class_eval do
scope :with_errors, where("last_error is NOT null")
# Quickly see offending jobs
class << self
def show_errors(n)
first(n).select.(&:last_error).map {|n| n.last_error.match(/^.*\n/)}
end
# Return array of jobs relating to a particular identifying_column
# example: id_column = "subject_id" gets all the effected subjects
def jobs_on_id_column(id_column)
all.map {|j| j.handler.match(/#{id_column}: '(.*)'/).try :[], 1 }.compact.uniq
end
def clear_failed
where("last_error is NOT null").destroy_all
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment