Skip to content

Commit a21921d

Browse files
committed
add wrapper for API routes
1 parent 46638d9 commit a21921d

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export { withSentryServerSideAppGetInitialProps } from './withSentryServerSideAp
44
export { withSentryServerSideDocumentGetInitialProps } from './withSentryServerSideDocumentGetInitialProps';
55
export { withSentryServerSideErrorGetInitialProps } from './withSentryServerSideErrorGetInitialProps';
66
export { withSentryGetServerSideProps } from './withSentryGetServerSideProps';
7+
export { withSentryAPI } from './withSentryAPI';
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// We import these types from `withSentry` rather than directly from `next` because our version can work simultaneously
2+
// with multiple versions of next. See note in `withSentry` for more.
3+
import type { NextApiHandler, WrappedNextApiHandler } from '../../utils/withSentry';
4+
import { withSentry } from '../../utils/withSentry';
5+
6+
/**
7+
* TODO
8+
*/
9+
export function withSentryAPI(
10+
maybeWrappedHandler: NextApiHandler | WrappedNextApiHandler,
11+
parameterizedRoute: string,
12+
): WrappedNextApiHandler {
13+
// We want the innards of `withSentry` to have access to the parameterized route, so it can be used when we start the
14+
// request transaction. If we were always the ones calling `withSentry` (the way we're always the ones to call
15+
// `withSentryServerSideProps`, for example), then we could just pass it in as a second parameter and know it would
16+
// always be there. But in the case where users have already manually wrapped their API route handlers with
17+
// `withSentry`, they're the ones calling it, without the parameterized route as a second parameter. We need a
18+
// different way to make it available.
19+
//
20+
// Fortunately, with some clever `this` usage, we can do it.
21+
22+
// First we add it as a property on the exported handler.
23+
maybeWrappedHandler.__sentry_route__ = parameterizedRoute;
24+
25+
// TODO: Finish explanation
26+
// TODO: Figure out if `maybeWrappedHandler` is `withSentry` itself or the results of calling `withSentry` on the original handler
27+
28+
if ('__sentry_wrapped__' in maybeWrappedHandler) {
29+
return wrapLite(maybeWrappedHandler);
30+
}
31+
32+
return withSentry(maybeWrappedHandler);
33+
}
34+
35+
// TODO: This needs a better name, and a docstring
36+
function wrapLite(alreadyWrappedHandler: WrappedNextApiHandler): WrappedNextApiHandler {
37+
const newWrapper: WrappedNextApiHandler = (req, res) => {
38+
// Make `alreadyWrappedHandler` its own `this`
39+
return alreadyWrappedHandler.call(alreadyWrappedHandler, req, res);
40+
};
41+
42+
return newWrapper;
43+
}

packages/nextjs/src/index.server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ export {
134134
withSentryServerSideAppGetInitialProps,
135135
withSentryServerSideDocumentGetInitialProps,
136136
withSentryServerSideErrorGetInitialProps,
137+
withSentryAPI,
137138
} from './config/wrappers';
138139
export { withSentry } from './utils/withSentry';
139140

0 commit comments

Comments
 (0)