Skip to content

Commit 4e6097c

Browse files
author
Luca Forstner
committed
Refactor new filtering logic
1 parent ba3f500 commit 4e6097c

File tree

2 files changed

+68
-51
lines changed

2 files changed

+68
-51
lines changed

packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,18 @@ function parseOriginalCodeFrame(codeFrame: string): {
122122
* in the dev overlay.
123123
*/
124124
export async function devErrorSymbolicationEventProcessor(event: Event, hint: EventHint): Promise<Event | null> {
125+
// Filter out spans for requests resolving source maps for stack frames in dev mode
126+
if (event.type === 'transaction') {
127+
event.spans = event.spans?.filter(span => {
128+
const httpUrlAttribute: unknown = span.data?.['http.url'];
129+
if (typeof httpUrlAttribute === 'string') {
130+
return !httpUrlAttribute.includes('__nextjs_original-stack-frame');
131+
}
132+
133+
return true;
134+
});
135+
}
136+
125137
// Due to changes across Next.js versions, there are a million things that can go wrong here so we just try-catch the // entire event processor.Symbolicated stack traces are just a nice to have.
126138
try {
127139
if (hint.originalException && hint.originalException instanceof Error && hint.originalException.stack) {

packages/nextjs/src/server/index.ts

Lines changed: 56 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -113,60 +113,65 @@ export function init(options: NodeOptions): void {
113113

114114
nodeInit(opts);
115115

116-
const filterLowQualityTransactions: EventProcessor = event => {
117-
if (event.type === 'transaction') {
118-
// Filter out transactions for static assets
119-
// This regex matches the default path to the static assets (`_next/static`) and could potentially filter out too many transactions.
120-
// We match `/_next/static/` anywhere in the transaction name because its location may change with the basePath setting.
121-
if (event.transaction?.match(/^GET (\/.*)?\/_next\/static\//)) {
122-
return null;
123-
}
124-
125-
// Filter out transactions for requests to the tunnel route
126-
if (
127-
globalWithInjectedValues.__sentryRewritesTunnelPath__ &&
128-
event.transaction === `POST ${globalWithInjectedValues.__sentryRewritesTunnelPath__}`
129-
) {
130-
return null;
131-
}
132-
133-
// Filter out requests to resolve source maps for stack frames in dev mode
134-
if (event.transaction?.match(/\/__nextjs_original-stack-frame/)) {
135-
return null;
136-
}
137-
138-
return event;
139-
} else {
140-
return event;
141-
}
142-
};
143-
filterLowQualityTransactions.id = 'NextLowQualityTransactionsFilter';
144-
addEventProcessor(filterLowQualityTransactions);
145-
146-
const filterSentrySpans: EventProcessor = event => {
147-
if (event.type === 'transaction') {
148-
event.spans = event.spans?.filter(span => {
149-
// Filter out spans for Sentry event sends
150-
const httpTargetAttribute: unknown = span.data?.['http.target'];
151-
if (typeof httpTargetAttribute === 'string') {
152-
// TODO: Find a more robust matching logic
153-
return !httpTargetAttribute.includes('sentry_client') && !httpTargetAttribute.includes('sentry_key');
116+
addEventProcessor(
117+
Object.assign(
118+
(event => {
119+
if (event.type === 'transaction') {
120+
// Filter out transactions for static assets
121+
// This regex matches the default path to the static assets (`_next/static`) and could potentially filter out too many transactions.
122+
// We match `/_next/static/` anywhere in the transaction name because its location may change with the basePath setting.
123+
if (event.transaction?.match(/^GET (\/.*)?\/_next\/static\//)) {
124+
return null;
125+
}
126+
127+
// Filter out transactions for requests to the tunnel route
128+
if (
129+
globalWithInjectedValues.__sentryRewritesTunnelPath__ &&
130+
event.transaction === `POST ${globalWithInjectedValues.__sentryRewritesTunnelPath__}`
131+
) {
132+
return null;
133+
}
134+
135+
// Filter out requests to resolve source maps for stack frames in dev mode
136+
if (event.transaction?.match(/\/__nextjs_original-stack-frame/)) {
137+
return null;
138+
}
139+
140+
// Filter out /404 transactions for pages-router which seem to be created excessively
141+
if (event.transaction === '/404') {
142+
return null;
143+
}
144+
145+
return event;
146+
} else {
147+
return event;
154148
}
155-
156-
// Filter out requests to resolve source maps for stack frames in dev mode
157-
const httpUrlAttribute: unknown = span.data?.['http.url'];
158-
if (typeof httpUrlAttribute === 'string') {
159-
return !httpUrlAttribute.includes('__nextjs_original-stack-frame');
149+
}) satisfies EventProcessor,
150+
{ id: 'NextLowQualityTransactionsFilter' },
151+
),
152+
);
153+
154+
addEventProcessor(
155+
Object.assign(
156+
(event => {
157+
if (event.type === 'transaction') {
158+
event.spans = event.spans?.filter(span => {
159+
// Filter out spans for Sentry event sends
160+
const httpTargetAttribute: unknown = span.data?.['http.target'];
161+
if (typeof httpTargetAttribute === 'string') {
162+
// TODO: Find a more robust matching logic - We likely want to use the OTEL SDK's `suppressTracing` in our transport, if we end up using it, we can delete this filtering logic here.
163+
return !httpTargetAttribute.includes('sentry_client') && !httpTargetAttribute.includes('sentry_key');
164+
}
165+
166+
return true;
167+
});
160168
}
161169

162-
return true;
163-
});
164-
}
165-
166-
return event;
167-
};
168-
filterSentrySpans.id = 'NextFilterSentrySpans';
169-
addEventProcessor(filterSentrySpans);
170+
return event;
171+
}) satisfies EventProcessor,
172+
{ id: 'NextFilterSentrySpans' },
173+
),
174+
);
170175

171176
// TODO(v8): Remove these tags
172177
setTag('runtime', 'node');

0 commit comments

Comments
 (0)