|
| 1 | +import { getActiveTransaction } from '@sentry/tracing'; |
| 2 | + |
1 | 3 | import { DataFetchingFunction } from './types';
|
2 | 4 |
|
3 | 5 | /**
|
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. |
6 | 7 | *
|
7 | 8 | * @template T Types for `getInitialProps`, `getStaticProps`, and `getServerSideProps`
|
8 | 9 | * @param origFunction The user's exported `getInitialProps`, `getStaticProps`, or `getServerSideProps` function
|
9 | 10 | * @param context The context object passed by nextjs to the function
|
| 11 | + * @param route The route currently being served |
10 | 12 | * @returns The result of calling the user's function
|
11 | 13 | */
|
12 |
| -export async function callOriginal<T extends DataFetchingFunction>( |
| 14 | +export async function wrapperCore<T extends DataFetchingFunction>( |
13 | 15 | origFunction: T['fn'],
|
14 | 16 | context: T['context'],
|
| 17 | + route: string, |
15 | 18 | ): Promise<T['result']> {
|
16 |
| - let props; |
| 19 | + const transaction = getActiveTransaction(); |
| 20 | + |
| 21 | + if (transaction) { |
| 22 | + // Pull off any leading underscores we've added in the process of wrapping the function |
| 23 | + const wrappedFunctionName = origFunction.name.replace(/^_*/, ''); |
| 24 | + |
| 25 | + // TODO: Make sure that the given route matches the name of the active transaction (to prevent background data |
| 26 | + // fetching from switching the name to a completely other route) |
| 27 | + transaction.name = route; |
| 28 | + transaction.metadata.source = 'route'; |
| 29 | + |
| 30 | + // Capture the route, since pre-loading, revalidation, etc might mean that this span may happen during another |
| 31 | + // route's transaction |
| 32 | + const span = transaction.startChild({ op: 'nextjs.data', description: `${wrappedFunctionName} (${route})` }); |
| 33 | + |
| 34 | + // TODO: Can't figure out how to tell TS that the types are correlated - that a `GSPropsFunction` will only get passed |
| 35 | + // `GSPropsContext` and never, say, `GSSPContext`. That's what wrapping everything in objects and using the generic |
| 36 | + // and pulling the types from the generic rather than specifying them directly was supposed to do, but... no luck. |
| 37 | + // eslint-disable-next-line prefer-const, @typescript-eslint/no-explicit-any |
| 38 | + const props = await (origFunction as any)(context); |
| 39 | + |
| 40 | + span.finish(); |
17 | 41 |
|
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); |
| 42 | + return props; |
| 43 | + } |
23 | 44 |
|
24 |
| - return props; |
| 45 | + // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 46 | + return (origFunction as any)(context); |
25 | 47 | }
|
0 commit comments