From 6bbf8d647d87295398021117a62daec54192ad1d Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Fri, 25 Feb 2022 13:21:44 +0100 Subject: [PATCH] Implement ErrorReporter#disable Ref: https://github.com/rails/rails/pull/43625#discussion_r809532572 It can be used by error reporting service integration when they wish to handle the error higher in the stack. For instance Sidekiq has its own error handling interface with a little bit of extra context information. --- .../lib/active_support/error_reporter.rb | 20 ++++++++++++++++++- activesupport/test/error_reporter_test.rb | 14 +++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/error_reporter.rb b/activesupport/lib/active_support/error_reporter.rb index bb8ab05813..25ff0f51cb 100644 --- a/activesupport/lib/active_support/error_reporter.rb +++ b/activesupport/lib/active_support/error_reporter.rb @@ -80,6 +80,21 @@ module ActiveSupport @subscribers << subscriber end + # Prevent a subscriber from being notified of errors for the + # duration of the block. + # + # It can be used by error reporting service integration when they wish + # to handle the error higher in the stack. + def disable(subscriber) + disabled_subscribers = (ActiveSupport::IsolatedExecutionState[self] ||= []) + disabled_subscribers << subscriber + begin + yield + ensure + disabled_subscribers.delete(subscriber) + end + end + # Update the execution context that is accessible to error subscribers # # Rails.error.set_context(section: "checkout", user_id: @user.id) @@ -98,8 +113,11 @@ module ActiveSupport end full_context = ActiveSupport::ExecutionContext.to_h.merge(context) + disabled_subscribers = ActiveSupport::IsolatedExecutionState[self] @subscribers.each do |subscriber| - subscriber.report(error, handled: handled, severity: severity, context: full_context) + unless disabled_subscribers&.any? { |s| s === subscriber } + subscriber.report(error, handled: handled, severity: severity, context: full_context) + end rescue => subscriber_error if logger logger.fatal( diff --git a/activesupport/test/error_reporter_test.rb b/activesupport/test/error_reporter_test.rb index 50f605c772..4423db86a4 100644 --- a/activesupport/test/error_reporter_test.rb +++ b/activesupport/test/error_reporter_test.rb @@ -41,6 +41,20 @@ class ErrorReporterTest < ActiveSupport::TestCase assert_equal [[error, true, :warning, { section: "public" }]], @subscriber.events end + test "#disable allow to skip a subscriber" do + @reporter.disable(@subscriber) do + @reporter.report(ArgumentError.new("Oops"), handled: true) + end + assert_equal [], @subscriber.events + end + + test "#disable allow to skip a subscribers per class" do + @reporter.disable(ErrorSubscriber) do + @reporter.report(ArgumentError.new("Oops"), handled: true) + end + assert_equal [], @subscriber.events + end + test "#handle swallow and report any unhandled error" do error = ArgumentError.new("Oops") @reporter.handle do