Skip to content

Commit c09cab8

Browse files
authored
fix(nextjs): Don't assert existence of req and res in data-fetching wrappers (#5866)
1 parent b7c0e54 commit c09cab8

4 files changed

+39
-51
lines changed

packages/nextjs/src/config/wrappers/withSentryServerSideAppGetInitialProps.ts

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,27 +28,23 @@ export function withSentryServerSideAppGetInitialProps(origAppGetInitialProps: A
2828

2929
const errorWrappedAppGetInitialProps = withErrorInstrumentation(origAppGetInitialProps);
3030

31-
if (hasTracingEnabled()) {
32-
// Since this wrapper is only applied to `getInitialProps` running on the server, we can assert that `req` and
33-
// `res` are always defined: https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#context-object
31+
// Generally we can assume that `req` and `res` are always defined on the server:
32+
// https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#context-object
33+
// This does not seem to be the case in dev mode. Because we have no clean way of associating the the data fetcher
34+
// span with each other when there are no req or res objects, we simply do not trace them at all here.
35+
if (hasTracingEnabled() && req && res) {
3436
const appGetInitialProps: {
3537
pageProps: {
3638
_sentryTraceData?: string;
3739
_sentryBaggage?: string;
3840
};
39-
} = await callTracedServerSideDataFetcher(
40-
errorWrappedAppGetInitialProps,
41-
appGetInitialPropsArguments,
42-
req!,
43-
res!,
44-
{
45-
dataFetcherRouteName: '/_app',
46-
requestedRouteName: context.ctx.pathname,
47-
dataFetchingMethodName: 'getInitialProps',
48-
},
49-
);
41+
} = await callTracedServerSideDataFetcher(errorWrappedAppGetInitialProps, appGetInitialPropsArguments, req, res, {
42+
dataFetcherRouteName: '/_app',
43+
requestedRouteName: context.ctx.pathname,
44+
dataFetchingMethodName: 'getInitialProps',
45+
});
5046

51-
const requestTransaction = getTransactionFromRequest(req!);
47+
const requestTransaction = getTransactionFromRequest(req);
5248
if (requestTransaction) {
5349
appGetInitialProps.pageProps._sentryTraceData = requestTransaction.toTraceparent();
5450

packages/nextjs/src/config/wrappers/withSentryServerSideDocumentGetInitialProps.ts

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,16 @@ export function withSentryServerSideDocumentGetInitialProps(
2929

3030
const errorWrappedGetInitialProps = withErrorInstrumentation(origDocumentGetInitialProps);
3131

32-
if (hasTracingEnabled()) {
33-
// Since this wrapper is only applied to `getInitialProps` running on the server, we can assert that `req` and
34-
// `res` are always defined: https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#context-object
35-
return callTracedServerSideDataFetcher(
36-
errorWrappedGetInitialProps,
37-
documentGetInitialPropsArguments,
38-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
39-
req!,
40-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
41-
res!,
42-
{
43-
dataFetcherRouteName: '/_document',
44-
requestedRouteName: context.pathname,
45-
dataFetchingMethodName: 'getInitialProps',
46-
},
47-
);
32+
// Generally we can assume that `req` and `res` are always defined on the server:
33+
// https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#context-object
34+
// This does not seem to be the case in dev mode. Because we have no clean way of associating the the data fetcher
35+
// span with each other when there are no req or res objects, we simply do not trace them at all here.
36+
if (hasTracingEnabled() && req && res) {
37+
return callTracedServerSideDataFetcher(errorWrappedGetInitialProps, documentGetInitialPropsArguments, req, res, {
38+
dataFetcherRouteName: '/_document',
39+
requestedRouteName: context.pathname,
40+
dataFetchingMethodName: 'getInitialProps',
41+
});
4842
} else {
4943
return errorWrappedGetInitialProps(...documentGetInitialPropsArguments);
5044
}

packages/nextjs/src/config/wrappers/withSentryServerSideErrorGetInitialProps.ts

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,21 @@ export function withSentryServerSideErrorGetInitialProps(
3131

3232
const errorWrappedGetInitialProps = withErrorInstrumentation(origErrorGetInitialProps);
3333

34-
if (hasTracingEnabled()) {
35-
// Since this wrapper is only applied to `getInitialProps` running on the server, we can assert that `req` and
36-
// `res` are always defined: https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#context-object
34+
// Generally we can assume that `req` and `res` are always defined on the server:
35+
// https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#context-object
36+
// This does not seem to be the case in dev mode. Because we have no clean way of associating the the data fetcher
37+
// span with each other when there are no req or res objects, we simply do not trace them at all here.
38+
if (hasTracingEnabled() && req && res) {
3739
const errorGetInitialProps: ErrorProps & {
3840
_sentryTraceData?: string;
3941
_sentryBaggage?: string;
40-
} = await callTracedServerSideDataFetcher(
41-
errorWrappedGetInitialProps,
42-
errorGetInitialPropsArguments,
43-
req!,
44-
res!,
45-
{
46-
dataFetcherRouteName: '/_error',
47-
requestedRouteName: context.pathname,
48-
dataFetchingMethodName: 'getInitialProps',
49-
},
50-
);
42+
} = await callTracedServerSideDataFetcher(errorWrappedGetInitialProps, errorGetInitialPropsArguments, req, res, {
43+
dataFetcherRouteName: '/_error',
44+
requestedRouteName: context.pathname,
45+
dataFetchingMethodName: 'getInitialProps',
46+
});
5147

52-
const requestTransaction = getTransactionFromRequest(req!);
48+
const requestTransaction = getTransactionFromRequest(req);
5349
if (requestTransaction) {
5450
errorGetInitialProps._sentryTraceData = requestTransaction.toTraceparent();
5551

packages/nextjs/src/config/wrappers/withSentryServerSideGetInitialProps.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,21 @@ export function withSentryServerSideGetInitialProps(origGetInitialProps: GetInit
2727

2828
const errorWrappedGetInitialProps = withErrorInstrumentation(origGetInitialProps);
2929

30-
if (hasTracingEnabled()) {
31-
// Since this wrapper is only applied to `getInitialProps` running on the server, we can assert that `req` and
32-
// `res` are always defined: https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#context-object
30+
// Generally we can assume that `req` and `res` are always defined on the server:
31+
// https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#context-object
32+
// This does not seem to be the case in dev mode. Because we have no clean way of associating the the data fetcher
33+
// span with each other when there are no req or res objects, we simply do not trace them at all here.
34+
if (hasTracingEnabled() && req && res) {
3335
const initialProps: {
3436
_sentryTraceData?: string;
3537
_sentryBaggage?: string;
36-
} = await callTracedServerSideDataFetcher(errorWrappedGetInitialProps, getInitialPropsArguments, req!, res!, {
38+
} = await callTracedServerSideDataFetcher(errorWrappedGetInitialProps, getInitialPropsArguments, req, res, {
3739
dataFetcherRouteName: context.pathname,
3840
requestedRouteName: context.pathname,
3941
dataFetchingMethodName: 'getInitialProps',
4042
});
4143

42-
const requestTransaction = getTransactionFromRequest(req!);
44+
const requestTransaction = getTransactionFromRequest(req);
4345
if (requestTransaction) {
4446
initialProps._sentryTraceData = requestTransaction.toTraceparent();
4547

0 commit comments

Comments
 (0)