Skip to content

Commit 4d2b165

Browse files
committed
feat(nextjs): Auto enable node http integration on server
1 parent 482ca02 commit 4d2b165

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed

packages/nextjs/src/index.server.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { RewriteFrames } from '@sentry/integrations';
2-
import { configureScope, init as nodeInit } from '@sentry/node';
2+
import { configureScope, init as nodeInit, Integrations } from '@sentry/node';
33

44
import { instrumentServer } from './utils/instrumentServer';
55
import { MetadataBuilder } from './utils/metadataBuilder';
@@ -37,12 +37,18 @@ const defaultRewriteFramesIntegration = new RewriteFrames({
3737
},
3838
});
3939

40+
const defaultHttpTracingIntegration = new Integrations.Http({ tracing: true });
41+
4042
function addServerIntegrations(options: NextjsOptions): void {
4143
if (options.integrations) {
4244
options.integrations = addIntegration(defaultRewriteFramesIntegration, options.integrations);
4345
} else {
4446
options.integrations = [defaultRewriteFramesIntegration];
4547
}
48+
49+
if (options.tracesSampleRate !== undefined || options.tracesSampler !== undefined) {
50+
options.integrations = addIntegration(defaultHttpTracingIntegration, options.integrations);
51+
}
4652
}
4753

4854
export { withSentryConfig } from './utils/config';
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { RewriteFrames } from '@sentry/integrations';
2+
import { Integrations } from '@sentry/node';
3+
import { Integration } from '@sentry/types';
4+
5+
import { init, Scope } from '../src/index.server';
6+
import { NextjsOptions } from '../src/utils/nextjsOptions';
7+
8+
const mockInit = jest.fn();
9+
let configureScopeCallback: (scope: Scope) => void = () => undefined;
10+
11+
jest.mock('@sentry/node', () => {
12+
const actual = jest.requireActual('@sentry/node');
13+
return {
14+
...actual,
15+
init: (options: NextjsOptions) => {
16+
mockInit(options);
17+
},
18+
configureScope: (callback: (scope: Scope) => void) => {
19+
configureScopeCallback = callback;
20+
},
21+
};
22+
});
23+
24+
describe('Server init()', () => {
25+
afterEach(() => {
26+
mockInit.mockClear();
27+
configureScopeCallback = () => undefined;
28+
});
29+
30+
it('inits the Node SDK', () => {
31+
expect(mockInit).toHaveBeenCalledTimes(0);
32+
init({});
33+
expect(mockInit).toHaveBeenCalledTimes(1);
34+
expect(mockInit).toHaveBeenLastCalledWith({
35+
_metadata: {
36+
sdk: {
37+
name: 'sentry.javascript.nextjs',
38+
version: expect.any(String),
39+
packages: expect.any(Array),
40+
},
41+
},
42+
autoSessionTracking: false,
43+
environment: 'test',
44+
integrations: [expect.any(RewriteFrames)],
45+
});
46+
});
47+
48+
it('sets runtime on scope', () => {
49+
const mockScope = new Scope();
50+
init({});
51+
configureScopeCallback(mockScope);
52+
// @ts-ignore need access to protected _tags attribute
53+
expect(mockScope._tags).toEqual({ runtime: 'node' });
54+
});
55+
56+
describe('integrations', () => {
57+
it('adds RewriteFrames integration by default', () => {
58+
init({});
59+
60+
const reactInitOptions: NextjsOptions = mockInit.mock.calls[0][0];
61+
expect(reactInitOptions.integrations).toHaveLength(1);
62+
const integrations = reactInitOptions.integrations as Integration[];
63+
expect(integrations[0]).toEqual(expect.any(RewriteFrames));
64+
});
65+
66+
it('adds Http integration by default if tracesSampleRate is set', () => {
67+
init({ tracesSampleRate: 1.0 });
68+
69+
const reactInitOptions: NextjsOptions = mockInit.mock.calls[0][0];
70+
expect(reactInitOptions.integrations).toHaveLength(2);
71+
const integrations = reactInitOptions.integrations as Integration[];
72+
expect(integrations[1]).toEqual(expect.any(Integrations.Http));
73+
});
74+
75+
it('adds Http integration by default if tracesSampler is set', () => {
76+
init({ tracesSampler: () => true });
77+
78+
const reactInitOptions: NextjsOptions = mockInit.mock.calls[0][0];
79+
expect(reactInitOptions.integrations).toHaveLength(2);
80+
const integrations = reactInitOptions.integrations as Integration[];
81+
expect(integrations[1]).toEqual(expect.any(Integrations.Http));
82+
});
83+
84+
it('adds Http integration with tracing true', () => {
85+
init({ tracesSampleRate: 1.0 });
86+
const reactInitOptions: NextjsOptions = mockInit.mock.calls[0][0];
87+
expect(reactInitOptions.integrations).toHaveLength(2);
88+
89+
const integrations = reactInitOptions.integrations as Integration[];
90+
expect((integrations[1] as any)._tracing).toBe(true);
91+
});
92+
});
93+
});

0 commit comments

Comments
 (0)