Skip to content

fix(sdk): filter third-party script errors out of the frontend SDK - #121862

Closed
JoshuaKGoldberg wants to merge 1 commit into
masterfrom
joshgoldberg/de-1511-filter-third-party-script-errors-out-of-the-frontend-sdk
Closed

fix(sdk): filter third-party script errors out of the frontend SDK#121862
JoshuaKGoldberg wants to merge 1 commit into
masterfrom
joshgoldberg/de-1511-filter-third-party-script-errors-out-of-the-frontend-sdk

Conversation

@JoshuaKGoldberg

@JoshuaKGoldberg JoshuaKGoldberg commented Aug 12, 2026

Copy link
Copy Markdown
Member

Note

Superseded by #121966.


Right now, we don't differentiate between crashes that are 100% in our own code vs. crashes that are partially (or completely!) third-party code. For example, if a browser extension throws an exception, we track that in our issues. That's a lot of annoying false noise.

beforeSend now drops an event when the stack has:

  • Any frame from a third-party source: as in, is "polluted" by code we don't own
  • No frame in the stack from code we serve ("first-party"): as in, is only unknown sources we can't be sure about

Note that this is essentially a more powerful Using thirdPartyErrorFilterIntegration. We'll not just filter out events including third parties (i.e. drop-error-if-contains-third-party-frames), we'll also get ones with no parties. We already use thirdPartyErrorFilterIntegration:

Sentry.thirdPartyErrorFilterIntegration({

Based on the attached measure_third_party_filter.py, the changes within all browser-SDK events in the javascript project are:

Issues Group Count Percentage
Total distinct issues (90d) 942 100.0%
Issues that would DISAPPEAR entirely (every event dropped) 277 29.4%
Issues that would lose some events but survive 20 2.1%
Issues affected at all 297 31.5%

If this goes in roughly as-is, I'll try to bring this up with the SDK team to see if we can make this a browser SDK feature. This problem is definitely not unique to us.

Closes DE-1511.

Vendor snippets and browser extensions throw on our pages without any frame
identifying them as foreign. Injected scripts have no file of their own, so the
browser attributes their frames to the document URL and the event reads as ours.

Drop an error when no frame in its stack comes from code we serve, and when any
frame names a source we know is not ours. Origins are derived from the page and
the asset prefix, so no vendor list needs maintaining. A stack with no frames at
all is kept, since it cannot be told apart from a real error that lost its stack.

Refs DE-1511
@linear-code

linear-code Bot commented Aug 12, 2026

Copy link
Copy Markdown

DE-1511

@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Aug 12, 2026
@JoshuaKGoldberg

Copy link
Copy Markdown
Member Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 843e2b6. Configure here.

@JoshuaKGoldberg JoshuaKGoldberg changed the title fix(sdk): Filter third-party script errors out of the frontend SDK fix(sdk): filter third-party script errors out of the frontend SDK Aug 12, 2026
@JoshuaKGoldberg
JoshuaKGoldberg marked this pull request as ready for review August 12, 2026 18:43
@JoshuaKGoldberg
JoshuaKGoldberg requested review from a team as code owners August 12, 2026 18:43
@JoshuaKGoldberg
JoshuaKGoldberg requested review from chargome, logaretm, msonnb and s1gr1d and removed request for a team August 12, 2026 18:43

@scttcper scttcper left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

down to try it, looks good

Comment on lines +842 to +851
it('returns true when every frame is anonymous', () => {
const event = eventWithFrames(
'<anonymous>',
'<anonymous>',
'<anonymous>',
'<anonymous>'
);

expect(isThirdPartyScriptEvent(event, ORIGINS)).toBeTruthy();
});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure that this is what we want? are there any cases like fetch() or service-worker; i'm thinking something more event driven where we control the event to an extent but not the early handler code?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow - do you mean like if we don't know anything, we should assume it's 100% foreign?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well idk what's best... my understanding is that built-in browser code is going to produce these <anonymous> frames?
So i was trying to think of reasonable situations where we'd have a fully anon stack and what that means.

i guess if there's an example of this that we've already captured then i'd look at that, but if we've never caught this case before (which is likely too) then i'm not worried.

Comment on lines +871 to +880
it('returns true when frames mix extension, vendor, and anonymous code', () => {
const event = eventWithFrames(
'chrome-extension://abcdefg/content.js',
'https://cdn.example.com/agent.js',
'<anonymous>',
'https://sentry.io/settings/'
);

expect(isThirdPartyScriptEvent(event, ORIGINS)).toBeTruthy();
});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense. extensions can use sentry themselves, which might make it look like our code. But because sandboxing those call stacks cannot interact with react et. al. on the page.

if (
isFilteredRequestErrorEvent(event) ||
isEventWithFileUrl(event) ||
isThirdPartyScriptEvent(event, firstPartyOrigins)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We gotta call out the difference between the new code and thirdPartyErrorFilterIntegration

@JoshuaKGoldberg

JoshuaKGoldberg commented Aug 13, 2026

Copy link
Copy Markdown
Member Author

I did a bit more digging and I'm seeing basically the same / slightly better results from Using thirdPartyErrorFilterIntegration -> 'drop-error-if-contains-third-party-frames'. :lolsob:. Will go with that!

@JoshuaKGoldberg

Copy link
Copy Markdown
Member Author

#121966

JoshuaKGoldberg added a commit that referenced this pull request Aug 14, 2026
Like #121862, but using our own product per its docs. 🥇 

See: [Using
`thirdPartyErrorFilterIntegration`](https://docs.sentry.io/platforms/javascript/configuration/filtering/#using-thirdpartyerrorfilterintegration)
-> `'drop-error-if-contains-third-party-frames'`.

Closes DE-1511.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants