Skip to content

Commit

Permalink
fix(nextjs): Stop sending transactions for requests that 404 (#4095)
Browse files Browse the repository at this point in the history
  • Loading branch information
lobsterkatie committed Nov 5, 2021
1 parent 9f1374d commit 60426d1
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/nextjs/src/index.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export function init(options: NextjsOptions): void {
});
configureScope(scope => {
scope.setTag('runtime', 'browser');
scope.addEventProcessor(event => (event.type === 'transaction' && event.transaction === '/404' ? null : event));
});
}

Expand Down
9 changes: 9 additions & 0 deletions packages/nextjs/src/index.server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Carrier, getHubFromCarrier, getMainCarrier } from '@sentry/hub';
import { RewriteFrames } from '@sentry/integrations';
import { configureScope, getCurrentHub, init as nodeInit, Integrations } from '@sentry/node';
import { Event } from '@sentry/types';
import { escapeStringForRegex, logger } from '@sentry/utils';
import * as domainModule from 'domain';
import * as path from 'path';
Expand Down Expand Up @@ -56,6 +57,8 @@ export function init(options: NextjsOptions): void {
if (process.env.VERCEL) {
scope.setTag('vercel', true);
}

scope.addEventProcessor(filterTransactions);
});

if (activeDomain) {
Expand All @@ -65,6 +68,8 @@ export function init(options: NextjsOptions): void {
// apply the changes made by `nodeInit` to the domain's hub also
domainHub.bindClient(globalHub.getClient());
domainHub.getScope()?.update(globalHub.getScope());
// `scope.update()` doesn’t copy over event processors, so we have to add it manually
domainHub.getScope()?.addEventProcessor(filterTransactions);

// restore the domain hub as the current one
domain.active = activeDomain;
Expand Down Expand Up @@ -107,6 +112,10 @@ function addServerIntegrations(options: NextjsOptions): void {
}
}

function filterTransactions(event: Event): Event | null {
return event.type === 'transaction' && event.transaction === '/404' ? null : event;
}

export { withSentryConfig } from './config';
export { withSentry } from './utils/withSentry';

Expand Down
23 changes: 21 additions & 2 deletions packages/nextjs/test/index.client.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { BaseClient } from '@sentry/core';
import { getCurrentHub } from '@sentry/hub';
import * as SentryReact from '@sentry/react';
import { Integrations as TracingIntegrations } from '@sentry/tracing';
import { Integration } from '@sentry/types';
import { getGlobalObject } from '@sentry/utils';
import { getGlobalObject, logger, SentryError } from '@sentry/utils';

import { init, Integrations, nextRouterInstrumentation } from '../src/index.client';
import { NextjsOptions } from '../src/utils/nextjsOptions';
Expand All @@ -12,10 +13,12 @@ const { BrowserTracing } = TracingIntegrations;
const global = getGlobalObject();

const reactInit = jest.spyOn(SentryReact, 'init');
const captureEvent = jest.spyOn(BaseClient.prototype, 'captureEvent');
const logError = jest.spyOn(logger, 'error');

describe('Client init()', () => {
afterEach(() => {
reactInit.mockClear();
jest.clearAllMocks();
global.__SENTRY__.hub = undefined;
});

Expand Down Expand Up @@ -50,6 +53,22 @@ describe('Client init()', () => {
expect(currentScope._tags).toEqual({ runtime: 'browser' });
});

it('adds 404 transaction filter', () => {
init({
dsn: 'https://dogsarebadatkeepingsecrets@squirrelchasers.ingest.sentry.io/12312012',
tracesSampleRate: 1.0,
});
const hub = getCurrentHub();
const sendEvent = jest.spyOn(hub.getClient()!.getTransport!(), 'sendEvent');

const transaction = hub.startTransaction({ name: '/404' });
transaction.finish();

expect(sendEvent).not.toHaveBeenCalled();
expect(captureEvent.mock.results[0].value).toBeUndefined();
expect(logError).toHaveBeenCalledWith(new SentryError('An event processor returned null, will not send event.'));
});

describe('integrations', () => {
it('does not add BrowserTracing integration by default if tracesSampleRate is not set', () => {
init({});
Expand Down
23 changes: 21 additions & 2 deletions packages/nextjs/test/index.server.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { BaseClient } from '@sentry/core';
import { RewriteFrames } from '@sentry/integrations';
import * as SentryNode from '@sentry/node';
import { getCurrentHub, NodeClient } from '@sentry/node';
import { Integration } from '@sentry/types';
import { getGlobalObject } from '@sentry/utils';
import { getGlobalObject, logger, SentryError } from '@sentry/utils';
import * as domain from 'domain';

import { init } from '../src/index.server';
Expand All @@ -16,10 +17,12 @@ const global = getGlobalObject();
(global as typeof global & { __rewriteFramesDistDir__: string }).__rewriteFramesDistDir__ = '.next';

const nodeInit = jest.spyOn(SentryNode, 'init');
const captureEvent = jest.spyOn(BaseClient.prototype, 'captureEvent');
const logError = jest.spyOn(logger, 'error');

describe('Server init()', () => {
afterEach(() => {
nodeInit.mockClear();
jest.clearAllMocks();
global.__SENTRY__.hub = undefined;
});

Expand Down Expand Up @@ -87,6 +90,22 @@ describe('Server init()', () => {
expect(currentScope._tags.vercel).toBeUndefined();
});

it('adds 404 transaction filter', () => {
init({
dsn: 'https://dogsarebadatkeepingsecrets@squirrelchasers.ingest.sentry.io/12312012',
tracesSampleRate: 1.0,
});
const hub = getCurrentHub();
const sendEvent = jest.spyOn(hub.getClient()!.getTransport!(), 'sendEvent');

const transaction = hub.startTransaction({ name: '/404' });
transaction.finish();

expect(sendEvent).not.toHaveBeenCalled();
expect(captureEvent.mock.results[0].value).toBeUndefined();
expect(logError).toHaveBeenCalledWith(new SentryError('An event processor returned null, will not send event.'));
});

it("initializes both global hub and domain hub when there's an active domain", () => {
const globalHub = getCurrentHub();
const local = domain.create();
Expand Down

0 comments on commit 60426d1

Please sign in to comment.