Skip to content

Commit

Permalink
Make callDataFetcherTraced async
Browse files Browse the repository at this point in the history
  • Loading branch information
lforst committed Aug 17, 2022
1 parent 7c93961 commit 02c1d43
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 31 deletions.
3 changes: 0 additions & 3 deletions packages/nextjs/src/config/loaders/dataFetchersLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ const DATA_FETCHING_FUNCTIONS = {
type LoaderOptions = {
projectDir: string;
pagesDir: string;
underscoreAppRegex: RegExp;
underscoreErrorRegex: RegExp;
underscoreDocumentRegex: RegExp;
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ type GetInitialProps = Required<NextPage<unknown>>['getInitialProps'];
* @returns A wrapped version of the function
*/
export function withSentryGetInitialProps(origGetInitialProps: GetInitialProps, route: string): GetInitialProps {
return function (...getInitialPropsArguments: Parameters<GetInitialProps>): ReturnType<GetInitialProps> {
return callDataFetcherTraced(origGetInitialProps, getInitialPropsArguments, { route, op: 'getInitialProps' });
return async function (
...getInitialPropsArguments: Parameters<GetInitialProps>
): Promise<ReturnType<GetInitialProps>> {
return await callDataFetcherTraced(origGetInitialProps, getInitialPropsArguments, { route, op: 'getInitialProps' });
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ export function withSentryGetServerSideProps(
origGetServerSideProps: GetServerSideProps,
route: string,
): GetServerSideProps {
return function (...getServerSidePropsArguments: Parameters<GetServerSideProps>): ReturnType<GetServerSideProps> {
return callDataFetcherTraced(origGetServerSideProps, getServerSidePropsArguments, {
return async function (
...getServerSidePropsArguments: Parameters<GetServerSideProps>
): ReturnType<GetServerSideProps> {
return await callDataFetcherTraced(origGetServerSideProps, getServerSidePropsArguments, {
route,
op: 'getServerSideProps',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export function withSentryGetStaticProps(
origGetStaticProps: GetStaticProps<Props>,
route: string,
): GetStaticProps<Props> {
return function (...getStaticPropsArguments: Parameters<GetStaticProps<Props>>): ReturnType<GetStaticProps<Props>> {
return callDataFetcherTraced(origGetStaticProps, getStaticPropsArguments, { route, op: 'getStaticProps' });
return async function (
...getStaticPropsArguments: Parameters<GetStaticProps<Props>>
): ReturnType<GetStaticProps<Props>> {
return await callDataFetcherTraced(origGetStaticProps, getStaticPropsArguments, { route, op: 'getStaticProps' });
};
}
29 changes: 7 additions & 22 deletions packages/nextjs/src/config/wrappers/wrapperUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import { Span } from '@sentry/types';
* We only do the following until we move transaction creation into this function: When called, the wrapped function
* will also update the name of the active transaction with a parameterized route provided via the `options` argument.
*/
export function callDataFetcherTraced<F extends (...args: any[]) => Promise<any> | any>(
export async function callDataFetcherTraced<F extends (...args: any[]) => Promise<any> | any>(
origFunction: F,
origFunctionArgs: Parameters<F>,
options: {
route: string;
op: string;
},
): ReturnType<F> {
): Promise<ReturnType<F>> {
const { route, op } = options;

const transaction = getActiveTransaction();
Expand All @@ -39,24 +39,9 @@ export function callDataFetcherTraced<F extends (...args: any[]) => Promise<any>
// route's transaction
const span = transaction.startChild({ op: 'nextjs.data', description: `${wrappedFunctionName} (${route})` });

const result = origFunction(...origFunctionArgs);

// We do the following instead of `await`-ing the return value of `origFunction`, because that would require us to
// make this function async which might in turn create a mismatch of function signatures between the original
// function and the wrapped one.
// This wraps `result`, which is potentially a Promise, into a Promise.
// If `result` is a non-Promise, the callback of `then` is immediately called and the span is finished.
// If `result` is a Promise, the callback of `then` is only called when `result` resolves
void Promise.resolve(result).then(
() => {
span.finish();
},
err => {
// TODO: Can we somehow associate the error with the span?
span.finish();
throw err;
},
);

return result;
try {
return await origFunction(...origFunctionArgs);
} finally {
span.finish();
}
}

0 comments on commit 02c1d43

Please sign in to comment.