Class: Bugsnag::Middleware::DelayedJob

Inherits:
Object
  • Object
show all
Defined in:
lib/bugsnag/middleware/delayed_job.rb

Overview

Attaches delayed_job information to an error report

Constant Summary collapse

ACTIVE_JOB_DISPLAY_NAME =

Active Job's queue adapter sets the “display_name” to this format. This breaks the event context as the ID and arguments are included, which will differ between executions of the same job

/^.* \[[0-9a-f-]+\] from DelayedJob\(.*\) with arguments: \[.*\]$/

Instance Method Summary collapse

Constructor Details

#initialize(bugsnag) ⇒ DelayedJob

Returns a new instance of DelayedJob.


10
11
12
# File 'lib/bugsnag/middleware/delayed_job.rb', line 10

def initialize(bugsnag)
  @bugsnag = bugsnag
end

Instance Method Details

#call(report) ⇒ Object


14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/bugsnag/middleware/delayed_job.rb', line 14

def call(report)
  job = report.request_data[:delayed_job]
  if job
    job_data = {
      :class => job.class.name,
      :id => job.id
    }
    job_data[:priority] = job.priority if job.respond_to?(:priority)
    job_data[:run_at] = job.run_at if job.respond_to?(:run_at)
    job_data[:locked_at] = job.locked_at if job.respond_to?(:locked_at)
    job_data[:locked_by] = job.locked_by if job.respond_to?(:locked_by)
    job_data[:created_at] = job.created_at if job.respond_to?(:created_at)
    job_data[:queue] = job.queue if job.respond_to?(:queue)

    if job.respond_to?(:payload_object)
      job_data[:active_job] = job.payload_object.job_data if job.payload_object.respond_to?(:job_data)
      payload_data = construct_job_payload(job.payload_object)

      context = get_context(payload_data, job_data[:active_job])
      report.automatic_context = context unless context.nil?

      job_data[:payload] = payload_data
    end

    if job.respond_to?(:attempts)
      # +1 as "attempts" is zero-based and does not include the current failed attempt
      job_data[:attempt] = job.attempts + 1
      job_data[:max_attempts] = (job.respond_to?(:max_attempts) && job.max_attempts) || Delayed::Worker.max_attempts
    end

    report.add_tab(:job, job_data)
  end
  @bugsnag.call(report)
end

#construct_job_payload(payload) ⇒ Object


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/bugsnag/middleware/delayed_job.rb', line 49

def construct_job_payload(payload)
  data = {
    :class => payload.class.name
  }
  data[:id]           = payload.id           if payload.respond_to?(:id)
  data[:display_name] = payload.display_name if payload.respond_to?(:display_name)
  data[:method_name]  = payload.method_name  if payload.respond_to?(:method_name)

  if payload.respond_to?(:args)
    data[:args] = payload.args
  elsif payload.respond_to?(:to_h)
    data[:args] = payload.to_h
  elsif payload.respond_to?(:instance_values)
    data[:args] = payload.instance_values
  end

  if payload.is_a?(::Delayed::PerformableMethod) && (object = payload.object)
    data[:object] = {
      :class => object.class.name
    }
    data[:object][:id] = object.id if object.respond_to?(:id)
  end
  if payload.respond_to?(:job_data) && payload.job_data.respond_to?(:[])
    [:job_class, :arguments, :queue_name, :job_id].each do |key|
      if (value = payload.job_data[key.to_s])
        data[key] = value
      end
    end
  end
  data
end