From 5e2635ff79ad07b7e2da15651de4ee8c19c1bbf8 Mon Sep 17 00:00:00 2001 From: Michael Hale Date: Wed, 6 Mar 2024 11:18:09 -0500 Subject: [PATCH 1/4] Add additional context to ActiveJob notifications --- lib/honeybadger/plugins/active_job.rb | 53 ++++++++++++------- .../rails/active_job_adapter_spec.rb | 30 +++++++++++ .../rails/async_queue_adapter_spec.rb | 19 ------- 3 files changed, 64 insertions(+), 38 deletions(-) create mode 100644 spec/integration/rails/active_job_adapter_spec.rb delete mode 100644 spec/integration/rails/async_queue_adapter_spec.rb diff --git a/lib/honeybadger/plugins/active_job.rb b/lib/honeybadger/plugins/active_job.rb index d626ac8b..1c645394 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:) + raise e + end + + def context(job) # rubocop:disable Metrics/MethodLength + { + arguments: job.arguments, + component: :good_job, + enqueued_at: job.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..9c3511f4 --- /dev/null +++ b/spec/integration/rails/active_job_adapter_spec.rb @@ -0,0 +1,30 @@ +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].context).to \ + include( + arguments: [{ some: 'data' }], + component: :good_job, + 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 From 1703e81176734c65505e7bed766839bf6f8122d4 Mon Sep 17 00:00:00 2001 From: Michael Hale Date: Thu, 7 Mar 2024 13:36:28 -0500 Subject: [PATCH 2/4] PR feedback --- lib/honeybadger/plugins/active_job.rb | 7 +++---- spec/integration/rails/active_job_adapter_spec.rb | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/honeybadger/plugins/active_job.rb b/lib/honeybadger/plugins/active_job.rb index 1c645394..f936475f 100644 --- a/lib/honeybadger/plugins/active_job.rb +++ b/lib/honeybadger/plugins/active_job.rb @@ -10,14 +10,13 @@ def perform_around(job, block) context = context(job) block.call rescue StandardError => e - Honeybadger.notify(e, context:) + Honeybadger.notify(e, context: context, parameters: { arguments: job.arguments }) raise e end - def context(job) # rubocop:disable Metrics/MethodLength + def context(job) { - arguments: job.arguments, - component: :good_job, + component: job.class, enqueued_at: job.enqueued_at, executions: job.executions, job_class: job.class, diff --git a/spec/integration/rails/active_job_adapter_spec.rb b/spec/integration/rails/active_job_adapter_spec.rb index 9c3511f4..751b9d0d 100644 --- a/spec/integration/rails/active_job_adapter_spec.rb +++ b/spec/integration/rails/active_job_adapter_spec.rb @@ -14,10 +14,10 @@ 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( - arguments: [{ some: 'data' }], - component: :good_job, + component: ErrorJob, enqueued_at: anything, executions: 1, job_class: ErrorJob, From c2de915b8d8703875d955da51d8d8035b1190151 Mon Sep 17 00:00:00 2001 From: Michael Hale Date: Thu, 7 Mar 2024 14:13:16 -0500 Subject: [PATCH 3/4] add action to context --- lib/honeybadger/plugins/active_job.rb | 3 ++- spec/integration/rails/active_job_adapter_spec.rb | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/honeybadger/plugins/active_job.rb b/lib/honeybadger/plugins/active_job.rb index f936475f..ab766251 100644 --- a/lib/honeybadger/plugins/active_job.rb +++ b/lib/honeybadger/plugins/active_job.rb @@ -14,9 +14,10 @@ def perform_around(job, block) raise e end - def context(job) + def context(job) # rubocop:disable Metrics/MethodLength { component: job.class, + action: 'perform', enqueued_at: job.enqueued_at, executions: job.executions, job_class: job.class, diff --git a/spec/integration/rails/active_job_adapter_spec.rb b/spec/integration/rails/active_job_adapter_spec.rb index 751b9d0d..98159dd2 100644 --- a/spec/integration/rails/active_job_adapter_spec.rb +++ b/spec/integration/rails/active_job_adapter_spec.rb @@ -18,6 +18,7 @@ expect(Honeybadger::Backend::Test.notifications[:notices][0].context).to \ include( component: ErrorJob, + action: 'perform', enqueued_at: anything, executions: 1, job_class: ErrorJob, From 84e4e2ad6ab8fb214456fdbf1d057eba05bf5d35 Mon Sep 17 00:00:00 2001 From: Michael Hale Date: Mon, 11 Mar 2024 16:44:03 -0400 Subject: [PATCH 4/4] rails 5.2 jobs do not have enqueued_at --- lib/honeybadger/plugins/active_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/honeybadger/plugins/active_job.rb b/lib/honeybadger/plugins/active_job.rb index ab766251..7f032f20 100644 --- a/lib/honeybadger/plugins/active_job.rb +++ b/lib/honeybadger/plugins/active_job.rb @@ -18,7 +18,7 @@ def context(job) # rubocop:disable Metrics/MethodLength { component: job.class, action: 'perform', - enqueued_at: job.enqueued_at, + enqueued_at: job.try(:enqueued_at), executions: job.executions, job_class: job.class, job_id: job.job_id,