Repository navigation
fix(rails): match excluded exceptions on subclasses and cause chain - #331
Merged
marandaneto merged 2 commits intoNov 10, 2026
Merged
Conversation
marandaneto
approved these changes
Nov 10, 2026
marandaneto
left a comment
Member
There was a problem hiding this comment.
The code looks good; no qualifying findings. Verdict: correct.
Preserve retry configuration and exclusion documentation. Use the shared cause-chain filter for Active Job retries to keep exclusions within the serialized chain limit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
💡 Motivation and Context
posthog-railschecksexcluded_exceptionswith an exact match on the outermost exception class name. However, two common cases are missing:Sidekiq::JobRetry::Handledwith the real error as itscause. ListingSidekiq::Limiter::OverLimittherefore excludes nothing, because the top-level exception class is the wrapper. E.g. in our production app this caused ~35k rate-limiter retries through in 6 hrs before I added abefore_sendfilter that walks$exception_list.The sdk-specs "Ignored exception types" requirement covers this. Matching must consider every exception in the chain and SDK holding the live error object may match subtypes.
This PR brings
excluded_exceptionsin line with that, for the pathsposthog-railscaptures automatically:Configuration#should_capture_exception?walks the cause chain, up toExceptionCapture::MAX_CHAINED_EXCEPTIONS(the number of links SDK serializes into$exception_list). It excludes an exception when any link is an instance of a listed class or of a subclass.auto_instrument_active_jobnow respectexcluded_exceptions. Before they were the only automatic path that ignored it.excluded_exceptionsYARD doc, the generator template and the example initializer document the matching rules.Behaviour change
More events are excluded than before: subclasses of listed classes, and exceptions raised while handling a listed one. With the built-in defaults an error raised inside
rescue ActiveRecord::RecordNotFoundblock is now dropped, because itscauseisRecordNotFound. FYIsentry-rubybehaves the same way (inspect_exception_causes_for_exclusionis on by default). Among the default list the only subclass Rails ships isActionController::MissingExactTemplate < UnknownFormat, which Rails already answers with 406. I marked the changesetminorbecause of this, but happy to change it if needed.Remaining divergence from the spec
The spec also asks for the default list to be empty and for the rule to cover manual
PostHog.capture_exceptionand$exceptionevents sent throughcapture. This PR leaves both as they are: Rails apps rely on the default list, and applying it to manual captures would silently drop events people send on purpose.Open question
If you'd rather keep the built-in defaults outermost-only, or add a switch like sentry-ruby
inspect_exception_causes_for_exclusion- again, happy to change it.before_sendalready lets an app restore the old behaviour, so I didn't add a new option.💚 How did you test it?
configurationover the installed gem📝 Checklist
If releasing new changes
pnpm changesetto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)