Module: Errsight::Integrations::ActiveJob

Extended by:
ActiveSupport::Concern
Defined in:
lib/errsight/integrations/active_job.rb

Overview

ActiveJob integration. Closes the scope-propagation gap for queue adapters that aren’t Sidekiq — Solid Queue (Rails 8 default), GoodJob, Delayed::Job’s AJ adapter, etc.

Two responsibilities:

1. Snapshot the current scope into the serialized job hash on
   enqueue, rehydrate it on dequeue. Same "user breadcrumbs only"
   rule as Sidekiq client/server middleware (Scope#to_h enforces
   this).

2. Capture exceptions raised inside `perform` with structured
   ActiveJob context (job class, queue, executions, adapter).
   Deduped against Rails.error.subscribe + Sidekiq middleware via
   the shared thread-local seen-set.

When the customer uses Sidekiq+ActiveJob, both our Sidekiq middleware and this layer fire. The dedup ensures one event per error; the outermost capturer wins on tags. ActiveJob-wrapped Sidekiq jobs already get correct unwrapped worker name + args from the Sidekiq middleware, so the redundancy is harmless.

Constant Summary collapse

MAX_ARG_BYTES =
4_096

Instance Method Summary collapse

Instance Method Details

#deserialize(job_data) ⇒ Object

Capture the snapshot back. ActiveJob calls deserialize before perform; we stash it on the job instance rather than push to the hub here because perform happens later (around_perform is the right place to push so the scope unwinds at perform end).



48
49
50
51
# File 'lib/errsight/integrations/active_job.rb', line 48

def deserialize(job_data)
  super
  @__errsight_scope_snapshot = job_data["errsight_scope"]
end

#serializeObject

Snapshot scope at enqueue time. ActiveJob calls ‘serialize` to produce the wire payload that adapters store; our override appends a scope key. Adapter-agnostic: works for any backend that round-trips the serialized hash.



37
38
39
40
41
42
# File 'lib/errsight/integrations/active_job.rb', line 37

def serialize
  super.tap do |hash|
    snapshot = Errsight.current_scope.to_h
    hash["errsight_scope"] = snapshot unless snapshot.empty?
  end
end