Skip to content

fix(nextjs): Pass this through wrappers #6572

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 14 additions & 18 deletions packages/nextjs/src/config/wrappers/withSentryGetServerSideProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { dynamicSamplingContextToSentryBaggageHeader } from '@sentry/utils';
import { GetServerSideProps } from 'next';

import { isBuild } from '../../utils/isBuild';
import { callTracedServerSideDataFetcher, getTransactionFromRequest, withErrorInstrumentation } from './wrapperUtils';
import { getTransactionFromRequest, withErrorInstrumentation, withTracedServerSideDataFetcher } from './wrapperUtils';

/**
* Create a wrapped version of the user's exported `getServerSideProps` function
Expand All @@ -16,30 +16,26 @@ export function withSentryGetServerSideProps(
origGetServerSideProps: GetServerSideProps,
parameterizedRoute: string,
): GetServerSideProps {
return async function (
...getServerSidePropsArguments: Parameters<GetServerSideProps>
): ReturnType<GetServerSideProps> {
return async function (this: unknown, ...args: Parameters<GetServerSideProps>): ReturnType<GetServerSideProps> {
if (isBuild()) {
return origGetServerSideProps(...getServerSidePropsArguments);
return origGetServerSideProps.apply(this, args);
}

const [context] = getServerSidePropsArguments;
const [context] = args;
const { req, res } = context;

const errorWrappedGetServerSideProps = withErrorInstrumentation(origGetServerSideProps);

if (hasTracingEnabled()) {
const serverSideProps = await callTracedServerSideDataFetcher(
errorWrappedGetServerSideProps,
getServerSidePropsArguments,
req,
res,
{
dataFetcherRouteName: parameterizedRoute,
requestedRouteName: parameterizedRoute,
dataFetchingMethodName: 'getServerSideProps',
},
);
const tracedGetServerSideProps = withTracedServerSideDataFetcher(errorWrappedGetServerSideProps, req, res, {
dataFetcherRouteName: parameterizedRoute,
requestedRouteName: parameterizedRoute,
dataFetchingMethodName: 'getServerSideProps',
});

const serverSideProps = await (tracedGetServerSideProps.apply(this, args) as ReturnType<
typeof tracedGetServerSideProps
>);

if ('props' in serverSideProps) {
const requestTransaction = getTransactionFromRequest(req);
Expand All @@ -53,7 +49,7 @@ export function withSentryGetServerSideProps(

return serverSideProps;
} else {
return errorWrappedGetServerSideProps(...getServerSidePropsArguments);
return errorWrappedGetServerSideProps.apply(this, args);
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { dynamicSamplingContextToSentryBaggageHeader } from '@sentry/utils';
import App from 'next/app';

import { isBuild } from '../../utils/isBuild';
import { callTracedServerSideDataFetcher, getTransactionFromRequest, withErrorInstrumentation } from './wrapperUtils';
import { getTransactionFromRequest, withErrorInstrumentation, withTracedServerSideDataFetcher } from './wrapperUtils';

type AppGetInitialProps = typeof App['getInitialProps'];

Expand All @@ -16,14 +16,12 @@ type AppGetInitialProps = typeof App['getInitialProps'];
* @returns A wrapped version of the function
*/
export function withSentryServerSideAppGetInitialProps(origAppGetInitialProps: AppGetInitialProps): AppGetInitialProps {
return async function (
...appGetInitialPropsArguments: Parameters<AppGetInitialProps>
): ReturnType<AppGetInitialProps> {
return async function (this: unknown, ...args: Parameters<AppGetInitialProps>): ReturnType<AppGetInitialProps> {
if (isBuild()) {
return origAppGetInitialProps(...appGetInitialPropsArguments);
return origAppGetInitialProps.apply(this, args);
}

const [context] = appGetInitialPropsArguments;
const [context] = args;
const { req, res } = context.ctx;

const errorWrappedAppGetInitialProps = withErrorInstrumentation(origAppGetInitialProps);
Expand All @@ -33,16 +31,18 @@ export function withSentryServerSideAppGetInitialProps(origAppGetInitialProps: A
// This does not seem to be the case in dev mode. Because we have no clean way of associating the the data fetcher
// span with each other when there are no req or res objects, we simply do not trace them at all here.
if (hasTracingEnabled() && req && res) {
const tracedGetInitialProps = withTracedServerSideDataFetcher(errorWrappedAppGetInitialProps, req, res, {
dataFetcherRouteName: '/_app',
requestedRouteName: context.ctx.pathname,
dataFetchingMethodName: 'getInitialProps',
});

const appGetInitialProps: {
pageProps: {
_sentryTraceData?: string;
_sentryBaggage?: string;
};
} = await callTracedServerSideDataFetcher(errorWrappedAppGetInitialProps, appGetInitialPropsArguments, req, res, {
dataFetcherRouteName: '/_app',
requestedRouteName: context.ctx.pathname,
dataFetchingMethodName: 'getInitialProps',
});
} = await tracedGetInitialProps.apply(this, args);

const requestTransaction = getTransactionFromRequest(req);

Expand All @@ -64,7 +64,7 @@ export function withSentryServerSideAppGetInitialProps(origAppGetInitialProps: A

return appGetInitialProps;
} else {
return errorWrappedAppGetInitialProps(...appGetInitialPropsArguments);
return errorWrappedAppGetInitialProps.apply(this, args);
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { hasTracingEnabled } from '@sentry/tracing';
import Document from 'next/document';

import { isBuild } from '../../utils/isBuild';
import { callTracedServerSideDataFetcher, withErrorInstrumentation } from './wrapperUtils';
import { withErrorInstrumentation, withTracedServerSideDataFetcher } from './wrapperUtils';

type DocumentGetInitialProps = typeof Document.getInitialProps;

Expand All @@ -18,13 +18,14 @@ export function withSentryServerSideDocumentGetInitialProps(
origDocumentGetInitialProps: DocumentGetInitialProps,
): DocumentGetInitialProps {
return async function (
...documentGetInitialPropsArguments: Parameters<DocumentGetInitialProps>
this: unknown,
...args: Parameters<DocumentGetInitialProps>
): ReturnType<DocumentGetInitialProps> {
if (isBuild()) {
return origDocumentGetInitialProps(...documentGetInitialPropsArguments);
return origDocumentGetInitialProps.apply(this, args);
}

const [context] = documentGetInitialPropsArguments;
const [context] = args;
const { req, res } = context;

const errorWrappedGetInitialProps = withErrorInstrumentation(origDocumentGetInitialProps);
Expand All @@ -34,13 +35,15 @@ export function withSentryServerSideDocumentGetInitialProps(
// This does not seem to be the case in dev mode. Because we have no clean way of associating the the data fetcher
// span with each other when there are no req or res objects, we simply do not trace them at all here.
if (hasTracingEnabled() && req && res) {
return callTracedServerSideDataFetcher(errorWrappedGetInitialProps, documentGetInitialPropsArguments, req, res, {
const tracedGetInitialProps = withTracedServerSideDataFetcher(errorWrappedGetInitialProps, req, res, {
dataFetcherRouteName: '/_document',
requestedRouteName: context.pathname,
dataFetchingMethodName: 'getInitialProps',
});

return await tracedGetInitialProps.apply(this, args);
} else {
return errorWrappedGetInitialProps(...documentGetInitialPropsArguments);
return errorWrappedGetInitialProps.apply(this, args);
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { NextPageContext } from 'next';
import { ErrorProps } from 'next/error';

import { isBuild } from '../../utils/isBuild';
import { callTracedServerSideDataFetcher, getTransactionFromRequest, withErrorInstrumentation } from './wrapperUtils';
import { getTransactionFromRequest, withErrorInstrumentation, withTracedServerSideDataFetcher } from './wrapperUtils';

type ErrorGetInitialProps = (context: NextPageContext) => Promise<ErrorProps>;

Expand All @@ -19,14 +19,12 @@ type ErrorGetInitialProps = (context: NextPageContext) => Promise<ErrorProps>;
export function withSentryServerSideErrorGetInitialProps(
origErrorGetInitialProps: ErrorGetInitialProps,
): ErrorGetInitialProps {
return async function (
...errorGetInitialPropsArguments: Parameters<ErrorGetInitialProps>
): ReturnType<ErrorGetInitialProps> {
return async function (this: unknown, ...args: Parameters<ErrorGetInitialProps>): ReturnType<ErrorGetInitialProps> {
if (isBuild()) {
return origErrorGetInitialProps(...errorGetInitialPropsArguments);
return origErrorGetInitialProps.apply(this, args);
}

const [context] = errorGetInitialPropsArguments;
const [context] = args;
const { req, res } = context;

const errorWrappedGetInitialProps = withErrorInstrumentation(origErrorGetInitialProps);
Expand All @@ -36,15 +34,17 @@ export function withSentryServerSideErrorGetInitialProps(
// This does not seem to be the case in dev mode. Because we have no clean way of associating the the data fetcher
// span with each other when there are no req or res objects, we simply do not trace them at all here.
if (hasTracingEnabled() && req && res) {
const errorGetInitialProps: ErrorProps & {
_sentryTraceData?: string;
_sentryBaggage?: string;
} = await callTracedServerSideDataFetcher(errorWrappedGetInitialProps, errorGetInitialPropsArguments, req, res, {
const tracedGetInitialProps = withTracedServerSideDataFetcher(errorWrappedGetInitialProps, req, res, {
dataFetcherRouteName: '/_error',
requestedRouteName: context.pathname,
dataFetchingMethodName: 'getInitialProps',
});

const errorGetInitialProps: ErrorProps & {
_sentryTraceData?: string;
_sentryBaggage?: string;
} = await tracedGetInitialProps.apply(this, args);

const requestTransaction = getTransactionFromRequest(req);
if (requestTransaction) {
errorGetInitialProps._sentryTraceData = requestTransaction.toTraceparent();
Expand All @@ -55,7 +55,7 @@ export function withSentryServerSideErrorGetInitialProps(

return errorGetInitialProps;
} else {
return errorWrappedGetInitialProps(...errorGetInitialPropsArguments);
return errorWrappedGetInitialProps.apply(this, args);
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { dynamicSamplingContextToSentryBaggageHeader } from '@sentry/utils';
import { NextPage } from 'next';

import { isBuild } from '../../utils/isBuild';
import { callTracedServerSideDataFetcher, getTransactionFromRequest, withErrorInstrumentation } from './wrapperUtils';
import { getTransactionFromRequest, withErrorInstrumentation, withTracedServerSideDataFetcher } from './wrapperUtils';

type GetInitialProps = Required<NextPage>['getInitialProps'];

Expand All @@ -15,14 +15,12 @@ type GetInitialProps = Required<NextPage>['getInitialProps'];
* @returns A wrapped version of the function
*/
export function withSentryServerSideGetInitialProps(origGetInitialProps: GetInitialProps): GetInitialProps {
return async function (
...getInitialPropsArguments: Parameters<GetInitialProps>
): Promise<ReturnType<GetInitialProps>> {
return async function (this: unknown, ...args: Parameters<GetInitialProps>): Promise<ReturnType<GetInitialProps>> {
if (isBuild()) {
return origGetInitialProps(...getInitialPropsArguments);
return origGetInitialProps.apply(this, args);
}

const [context] = getInitialPropsArguments;
const [context] = args;
const { req, res } = context;

const errorWrappedGetInitialProps = withErrorInstrumentation(origGetInitialProps);
Expand All @@ -32,15 +30,17 @@ export function withSentryServerSideGetInitialProps(origGetInitialProps: GetInit
// This does not seem to be the case in dev mode. Because we have no clean way of associating the the data fetcher
// span with each other when there are no req or res objects, we simply do not trace them at all here.
if (hasTracingEnabled() && req && res) {
const initialProps: {
_sentryTraceData?: string;
_sentryBaggage?: string;
} = await callTracedServerSideDataFetcher(errorWrappedGetInitialProps, getInitialPropsArguments, req, res, {
const tracedGetInitialProps = withTracedServerSideDataFetcher(errorWrappedGetInitialProps, req, res, {
dataFetcherRouteName: context.pathname,
requestedRouteName: context.pathname,
dataFetchingMethodName: 'getInitialProps',
});

const initialProps: {
_sentryTraceData?: string;
_sentryBaggage?: string;
} = await tracedGetInitialProps.apply(this, args);

const requestTransaction = getTransactionFromRequest(req);
if (requestTransaction) {
initialProps._sentryTraceData = requestTransaction.toTraceparent();
Expand All @@ -51,7 +51,7 @@ export function withSentryServerSideGetInitialProps(origGetInitialProps: GetInit

return initialProps;
} else {
return errorWrappedGetInitialProps(...getInitialPropsArguments);
return errorWrappedGetInitialProps.apply(this, args);
}
};
}
Loading