diff --git a/lib/honeybadger/plugins/active_job.rb b/lib/honeybadger/plugins/active_job.rb index d626ac8b..7f032f20 100644 --- a/lib/honeybadger/plugins/active_job.rb +++ b/lib/honeybadger/plugins/active_job.rb @@ -4,27 +4,42 @@ module ActiveJob # Ignore inline and test adapters, as well as the adapters that we support with their own plugins EXCLUDED_ADAPTERS = %i[inline test delayed_job faktory karafka resque shoryuken sidekiq sucker_punch].freeze - Plugin.register { - requirement { defined?(::Rails.application) && ::Rails.application } - requirement { - ::Rails.application.config.respond_to?(:active_job) && + class << self + def perform_around(job, block) + Honeybadger.clear! + context = context(job) + block.call + rescue StandardError => e + Honeybadger.notify(e, context: context, parameters: { arguments: job.arguments }) + raise e + end + + def context(job) # rubocop:disable Metrics/MethodLength + { + component: job.class, + action: 'perform', + enqueued_at: job.try(:enqueued_at), + executions: job.executions, + job_class: job.class, + job_id: job.job_id, + priority: job.priority, + queue_name: job.queue_name, + scheduled_at: job.scheduled_at + } + end + end + + Plugin.register do + requirement do + defined?(::Rails.application) && + ::Rails.application.config.respond_to?(:active_job) && !EXCLUDED_ADAPTERS.include?(::Rails.application.config.active_job[:queue_adapter]) - } + end - execution { - ::ActiveJob::Base.class_eval do |base| - base.set_callback :perform, :around do |param, block| - Honeybadger.clear! - begin - block.call - rescue => error - Honeybadger.notify(error, parameters: {job_id: job_id, arguments: arguments}) - raise error - end - end - end - } - } + execution do + ::ActiveJob::Base.set_callback(:perform, :around, &ActiveJob.method(:perform_around)) + end + end end end end diff --git a/spec/integration/rails/active_job_adapter_spec.rb b/spec/integration/rails/active_job_adapter_spec.rb new file mode 100644 index 00000000..98159dd2 --- /dev/null +++ b/spec/integration/rails/active_job_adapter_spec.rb @@ -0,0 +1,31 @@ +require_relative '../rails_helper' + +describe 'Rails ActiveJob Adapter Test', if: RAILS_PRESENT, type: :request do + include ActiveJob::TestHelper if RAILS_PRESENT + load_rails_hooks(self) + + it 'reports exceptions' do + Honeybadger.flush do + perform_enqueued_jobs do + expect do + ErrorJob.perform_later({ some: 'data' }) + end.to raise_error(StandardError) + end + end + + expect(Honeybadger::Backend::Test.notifications[:notices].size).to eq(1) + expect(Honeybadger::Backend::Test.notifications[:notices][0].params[:arguments][0]).to eq({ some: 'data' }) + expect(Honeybadger::Backend::Test.notifications[:notices][0].context).to \ + include( + component: ErrorJob, + action: 'perform', + enqueued_at: anything, + executions: 1, + job_class: ErrorJob, + job_id: anything, + priority: anything, + queue_name: 'default', + scheduled_at: anything + ) + end +end diff --git a/spec/integration/rails/async_queue_adapter_spec.rb b/spec/integration/rails/async_queue_adapter_spec.rb deleted file mode 100644 index 0af636a2..00000000 --- a/spec/integration/rails/async_queue_adapter_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -require_relative "../rails_helper" - -describe "Rails Async Queue Adapter Test", if: RAILS_PRESENT, type: :request do - include ActiveJob::TestHelper if RAILS_PRESENT - load_rails_hooks(self) - - it "reports exceptions" do - Honeybadger.flush do - perform_enqueued_jobs do - expect { - ErrorJob.perform_later({some: "data"}) - }.to raise_error(StandardError) - end - end - - expect(Honeybadger::Backend::Test.notifications[:notices].size).to eq(1) - expect(Honeybadger::Backend::Test.notifications[:notices][0].params[:arguments][0]).to eq({some: "data"}) - end -end