Skip to content

Commit 8d9bd40

Browse files
author
Luca Forstner
committed
feat(nextjs): Instrument SSR page components
1 parent a0ff516 commit 8d9bd40

File tree

4 files changed

+41
-1
lines changed

4 files changed

+41
-1
lines changed

packages/nextjs/src/common/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,5 @@ export { wrapRouteHandlerWithSentry } from './wrapRouteHandlerWithSentry';
4141
export { wrapApiHandlerWithSentryVercelCrons } from './wrapApiHandlerWithSentryVercelCrons';
4242

4343
export { wrapMiddlewareWithSentry } from './wrapMiddlewareWithSentry';
44+
45+
export { wrapPageComponentWithSentry } from './wrapPageComponentWithSentry';
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { captureException } from '@sentry/core';
2+
3+
/**
4+
* Wraps a page component with Sentry error instrumentation.
5+
*/
6+
export function wrapPageComponentWithSentry(pageComponent: any): unknown {
7+
const patchingTarget =
8+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
9+
typeof pageComponent.render === 'function'
10+
? // eslint-disable-next-line @typescript-eslint/unbound-method, @typescript-eslint/no-unsafe-member-access
11+
pageComponent.render
12+
: typeof pageComponent === 'function'
13+
? pageComponent
14+
: undefined;
15+
16+
if (patchingTarget === undefined) {
17+
return pageComponent;
18+
}
19+
20+
return new Proxy(patchingTarget, {
21+
apply(target, thisArg, argArray) {
22+
try {
23+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
24+
return target.apply(thisArg, argArray);
25+
} catch (e) {
26+
captureException(e);
27+
throw e;
28+
}
29+
},
30+
});
31+
}

packages/nextjs/src/config/templates/pageWrapperTemplate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const getServerSideProps =
4949
? Sentry.wrapGetServerSidePropsWithSentry(origGetServerSideProps, '__ROUTE__')
5050
: undefined;
5151

52-
export default pageComponent;
52+
export default pageComponent ? Sentry.wrapPageComponentWithSentry(pageComponent as any) : pageComponent;
5353

5454
// Re-export anything exported by the page module we're wrapping. When processing this code, Rollup is smart enough to
5555
// not include anything whose name matchs something we've explicitly exported above.

packages/nextjs/src/index.types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,10 @@ export declare function wrapApiHandlerWithSentryVercelCrons<F extends (...args:
186186
WrappingTarget: F,
187187
vercelCronsConfig: VercelCronsConfig,
188188
): F;
189+
190+
/**
191+
* Wraps a page component with Sentry error instrumentation.
192+
*/
193+
export declare function wrapPageComponentWithSentry<
194+
F extends ((...args: any[]) => any) | (new (...args: any[]) => any),
195+
>(WrappingTarget: F): F;

0 commit comments

Comments
 (0)