From c169e9a2883f239f53498c0d403421a758b49c4b Mon Sep 17 00:00:00 2001 From: Neel Shah Date: Tue, 25 Aug 2026 14:27:02 +0200 Subject: [PATCH] feat(data-collection): Gate ActiveJob arguments and ExecutionContext inclusion --- sentry-rails/lib/sentry/rails/active_job.rb | 18 +++++++---- .../lib/sentry/rails/capture_exceptions.rb | 5 ++- .../sentry/rails/error_reporter_context.rb | 2 -- .../shared_examples/argument_serialization.rb | 4 +++ .../shared_examples/error_context.rb | 31 ++++++++++++++++--- sentry-rails/spec/sentry/rails_spec.rb | 8 ++--- .../spec/versioned/2.7/activejob_spec.rb | 4 ++- sentry-ruby/lib/sentry/interfaces/request.rb | 4 +-- 8 files changed, 55 insertions(+), 21 deletions(-) diff --git a/sentry-rails/lib/sentry/rails/active_job.rb b/sentry-rails/lib/sentry/rails/active_job.rb index 229a44f6c..185a16836 100644 --- a/sentry-rails/lib/sentry/rails/active_job.rb +++ b/sentry-rails/lib/sentry/rails/active_job.rb @@ -220,18 +220,19 @@ def compute_latency(job) end def capture_exception(job, e) - Sentry::Rails.capture_exception( - e, + options = { extra: sentry_context(job), tags: { job_id: job.job_id, provider_job_id: job.provider_job_id }, - contexts: execution_context, # Send synchronously: a worker process may exit before the async # background worker flushes its queue, which would drop the event. hint: { background: false } - ) + } + options[:contexts] = execution_context if Sentry.configuration.data_collection.queues + + Sentry::Rails.capture_exception(e, **options) end def register_event_handlers @@ -272,14 +273,19 @@ def finish_sentry_transaction(transaction, status) end def sentry_context(job) - { + context = { active_job: job.class.name, - arguments: sentry_serialize_arguments(job.arguments), scheduled_at: job.scheduled_at, job_id: job.job_id, provider_job_id: job.provider_job_id, locale: job.locale } + + if Sentry.configuration.data_collection.queues + context[:arguments] = sentry_serialize_arguments(job.arguments) + end + + context end def sentry_serialize_arguments(argument) diff --git a/sentry-rails/lib/sentry/rails/capture_exceptions.rb b/sentry-rails/lib/sentry/rails/capture_exceptions.rb index ba53e7b13..756990ee7 100644 --- a/sentry-rails/lib/sentry/rails/capture_exceptions.rb +++ b/sentry-rails/lib/sentry/rails/capture_exceptions.rb @@ -34,7 +34,10 @@ def capture_exception(exception, env) return unless Sentry.initialized? return if show_exceptions?(exception, env) && !Sentry.configuration.rails.report_rescued_exceptions - Sentry::Rails.capture_exception(exception, contexts: execution_context).tap do |event| + options = {} + options[:contexts] = execution_context if Sentry.configuration.data_collection.user_info + + Sentry::Rails.capture_exception(exception, **options).tap do |event| env[ERROR_EVENT_ID_KEY] = event.event_id if event end end diff --git a/sentry-rails/lib/sentry/rails/error_reporter_context.rb b/sentry-rails/lib/sentry/rails/error_reporter_context.rb index 666b3b726..4ecfc72e4 100644 --- a/sentry-rails/lib/sentry/rails/error_reporter_context.rb +++ b/sentry-rails/lib/sentry/rails/error_reporter_context.rb @@ -9,8 +9,6 @@ module ErrorReporterContext if SUPPORTS_EXECUTION_CONTEXT def execution_context - return {} unless Sentry.configuration.send_default_pii - context = ::ActiveSupport::ExecutionContext.to_h return {} if context.empty? diff --git a/sentry-rails/spec/active_job/shared_examples/argument_serialization.rb b/sentry-rails/spec/active_job/shared_examples/argument_serialization.rb index 75fc1aff1..e0d4583a4 100644 --- a/sentry-rails/spec/active_job/shared_examples/argument_serialization.rb +++ b/sentry-rails/spec/active_job/shared_examples/argument_serialization.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true RSpec.shared_examples "an ActiveJob backend that serializes complex arguments" do + before do + Sentry.configuration.data_collection.queues = true + end + def event_arguments last_sentry_event.extra[:arguments] end diff --git a/sentry-rails/spec/active_job/shared_examples/error_context.rb b/sentry-rails/spec/active_job/shared_examples/error_context.rb index 7169094bb..69edbb7ee 100644 --- a/sentry-rails/spec/active_job/shared_examples/error_context.rb +++ b/sentry-rails/spec/active_job/shared_examples/error_context.rb @@ -21,9 +21,9 @@ def perform expect(event.extra).to include( active_job: failing_job.name, - arguments: [], job_id: a_kind_of(String) ) + expect(event.extra).not_to have_key(:arguments) expect(event.extra).to have_key(:provider_job_id) expect(event.extra).to have_key(:locale) expect(event.extra).to have_key(:scheduled_at) @@ -37,6 +37,29 @@ def perform expect(last_frame.vars).to include(a: "1", b: "0") end + context "when queue data collection is enabled" do + let(:configure_sentry) do + proc do |config| + config.data_collection.queues = true + end + end + + it "includes job arguments in the captured event" do + job = job_fixture do + def perform(_argument) + raise "boom from job with arguments" + end + end + + expect do + job.perform_later("sensitive argument") + drain + end.to raise_error(RuntimeError, /boom from job with arguments/) + + expect(last_sentry_event.extra[:arguments]).to eq(["sensitive argument"]) + end + end + context "with Rails.error.set_context data attached before the job raises", skip: RAILS_VERSION < 7.0 do let(:job_with_context) do job_fixture do @@ -61,14 +84,14 @@ def capture_job_error last_sentry_event end - it "omits the context from the captured event" do + it "omits the context from the captured event when queue data collection is disabled" do expect(capture_job_error.contexts).not_to have_key("rails.error") end - context "when send_default_pii is enabled" do + context "when queue data collection is enabled" do let(:configure_sentry) do proc do |config| - config.send_default_pii = true + config.data_collection.queues = true end end diff --git a/sentry-rails/spec/sentry/rails_spec.rb b/sentry-rails/spec/sentry/rails_spec.rb index 8ee6c9f66..904068987 100644 --- a/sentry-rails/spec/sentry/rails_spec.rb +++ b/sentry-rails/spec/sentry/rails_spec.rb @@ -366,12 +366,12 @@ def capture_in_separate_process(exit_code:) end context "when config.register_error_subscriber = true" do - let(:send_default_pii) { false } + let(:user_info) { false } before do make_basic_app do |config| config.rails.register_error_subscriber = true - config.send_default_pii = send_default_pii + config.data_collection.user_info = user_info end end @@ -420,8 +420,8 @@ def capture_in_separate_process(exit_code:) expect(transport.events.first.contexts).not_to have_key("rails.error") end - context "when send_default_pii is enabled" do - let(:send_default_pii) { true } + context "when user data collection is enabled" do + let(:user_info) { true } it "includes Rails.error.set_context data attached before an unhandled request exception" do get "/exception_with_error_context" diff --git a/sentry-rails/spec/versioned/2.7/activejob_spec.rb b/sentry-rails/spec/versioned/2.7/activejob_spec.rb index ee4e4d3dd..ab905a5fb 100644 --- a/sentry-rails/spec/versioned/2.7/activejob_spec.rb +++ b/sentry-rails/spec/versioned/2.7/activejob_spec.rb @@ -7,7 +7,9 @@ RSpec.describe "ActiveJob integration", type: :job do before do - make_basic_app + make_basic_app do |config| + config.data_collection.queues = true + end end let(:event) do diff --git a/sentry-ruby/lib/sentry/interfaces/request.rb b/sentry-ruby/lib/sentry/interfaces/request.rb index ad777ae8b..b840e5408 100644 --- a/sentry-ruby/lib/sentry/interfaces/request.rb +++ b/sentry-ruby/lib/sentry/interfaces/request.rb @@ -37,12 +37,10 @@ class RequestInterface < Interface # @param env [Hash] # @param data_collection [DataCollection] - # @param send_default_pii [Boolean] Deprecated compatibility input, unused. # @param rack_env_whitelist [Array] # @see Configuration#data_collection - # @see Configuration#send_default_pii # @see Configuration#rack_env_whitelist - def initialize(env:, data_collection:, rack_env_whitelist:, send_default_pii: nil) + def initialize(env:, data_collection:, rack_env_whitelist:) env = env.dup request = ::Rack::Request.new(env) query = data_collection.url_query_params.filter(request.GET) rescue nil