Skip to content

Commit be3a2fa

Browse files
committed
add span creation and transaction name replacement to wrapper core function
1 parent f6ff082 commit be3a2fa

File tree

3 files changed

+40
-19
lines changed

3 files changed

+40
-19
lines changed

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { GSSP } from './types';
2-
import { callOriginal } from './wrapperUtils';
2+
import { wrapperCore } from './wrapperUtils';
33

44
/**
55
* Create a wrapped version of the user's exported `getServerSideProps` function
@@ -10,6 +10,6 @@ import { callOriginal } from './wrapperUtils';
1010
*/
1111
export function withSentryGetServerSideProps(origGetServerSideProps: GSSP['fn'], route: string): GSSP['wrappedFn'] {
1212
return async function (context: GSSP['context']): Promise<GSSP['result']> {
13-
return callOriginal<GSSP>(origGetServerSideProps, context);
13+
return wrapperCore<GSSP>({ origFunction: origGetServerSideProps, context, route, op: 'getServerSideProps' });
1414
};
1515
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { GSProps } from './types';
2-
import { callOriginal } from './wrapperUtils';
2+
import { wrapperCore } from './wrapperUtils';
33

44
/**
55
* Create a wrapped version of the user's exported `getStaticProps` function
@@ -10,6 +10,6 @@ import { callOriginal } from './wrapperUtils';
1010
*/
1111
export function withSentryGetStaticProps(origGetStaticProps: GSProps['fn'], route: string): GSProps['wrappedFn'] {
1212
return async function (context: GSProps['context']): Promise<GSProps['result']> {
13-
return callOriginal<GSProps>(origGetStaticProps, context);
13+
return wrapperCore<GSProps>({ origFunction: origGetStaticProps, context, route, op: 'getStaticProps' });
1414
};
1515
}
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,46 @@
1+
import { getActiveTransaction } from '@sentry/tracing';
2+
13
import { DataFetchingFunction } from './types';
24

35
/**
4-
* Pass-through wrapper for the original function, used as a first step in eventually wrapping the data-fetching
5-
* functions with code for tracing.
6+
* Create a span to track the wrapped function and update transaction name with parameterized route.
67
*
78
* @template T Types for `getInitialProps`, `getStaticProps`, and `getServerSideProps`
89
* @param origFunction The user's exported `getInitialProps`, `getStaticProps`, or `getServerSideProps` function
910
* @param context The context object passed by nextjs to the function
1011
* @returns The result of calling the user's function
1112
*/
12-
export async function callOriginal<T extends DataFetchingFunction>(
13-
origFunction: T['fn'],
14-
context: T['context'],
15-
): Promise<T['result']> {
16-
let props;
17-
18-
// TODO: Can't figure out how to tell TS that the types are correlated - that a `GSPropsFunction` will only get passed
19-
// `GSPropsContext` and never, say, `GSSPContext`. That's what wrapping everything in objects and using the generic
20-
// and pulling the types from the generic rather than specifying them directly was supposed to do, but... no luck.
21-
// eslint-disable-next-line prefer-const, @typescript-eslint/no-explicit-any
22-
props = await (origFunction as any)(context);
23-
24-
return props;
13+
export async function wrapperCore<T extends DataFetchingFunction>(options: {
14+
origFunction: T['fn'];
15+
context: T['context'];
16+
route: string;
17+
op: string;
18+
}): Promise<T['result']> {
19+
const { origFunction, context, route, op } = options;
20+
21+
const transaction = getActiveTransaction();
22+
23+
if (transaction) {
24+
// TODO: Make sure that the given route matches the name of the active transaction (to prevent background data
25+
// fetching from switching the name to a completely other route)
26+
transaction.name = route;
27+
transaction.metadata.source = 'route';
28+
29+
// Capture the route, since pre-loading, revalidation, etc might mean that this span may happen during another
30+
// route's transaction
31+
const span = transaction.startChild({ op, data: { route } });
32+
33+
// TODO: Can't figure out how to tell TS that the types are correlated - that a `GSPropsFunction` will only get passed
34+
// `GSPropsContext` and never, say, `GSSPContext`. That's what wrapping everything in objects and using the generic
35+
// and pulling the types from the generic rather than specifying them directly was supposed to do, but... no luck.
36+
// eslint-disable-next-line prefer-const, @typescript-eslint/no-explicit-any
37+
const props = await (origFunction as any)(context);
38+
39+
span.finish();
40+
41+
return props;
42+
}
43+
44+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
45+
return (origFunction as any)(context);
2546
}

0 commit comments

Comments
 (0)