Skip to content

Commit 00482d8

Browse files
authored
fix(nextjs): Add isomorphic versions of ErrorBoundary, withErrorBoundary and showReportDialog (#6987)
1 parent 69beb14 commit 00482d8

File tree

4 files changed

+39
-5
lines changed

4 files changed

+39
-5
lines changed

packages/nextjs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
},
3838
"peerDependencies": {
3939
"next": "^10.0.8 || ^11.0 || ^12.0 || ^13.0",
40-
"react": "15.x || 16.x || 17.x || 18.x",
40+
"react": "16.x || 17.x || 18.x",
4141
"webpack": ">= 4.0.0"
4242
},
4343
"peerDependenciesMeta": {

packages/nextjs/src/index.types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ export declare function flush(timeout?: number | undefined): PromiseLike<boolean
3030
export declare function lastEventId(): string | undefined;
3131
export declare function getSentryRelease(fallback?: string): string | undefined;
3232

33+
export declare const ErrorBoundary: typeof clientSdk.ErrorBoundary;
34+
export declare const showReportDialog: typeof clientSdk.showReportDialog;
35+
export declare const withErrorBoundary: typeof clientSdk.withErrorBoundary;
36+
3337
/**
3438
* @deprecated Use `wrapApiHandlerWithSentry` instead
3539
*/

packages/nextjs/src/server/index.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,39 @@ import { isBuild } from './utils/isBuild';
1717
export * from '@sentry/node';
1818
export { captureUnderscoreErrorException } from '../common/_error';
1919

20-
// Here we want to make sure to only include what doesn't have browser specifics
21-
// because or SSR of next.js we can only use this.
22-
export { ErrorBoundary, showReportDialog, withErrorBoundary } from '@sentry/react';
20+
/**
21+
* A passthrough error boundary for the server that doesn't depend on any react. Error boundaries don't catch SSR errors
22+
* so they should simply be a passthrough.
23+
*/
24+
export const ErrorBoundary = (props: React.PropsWithChildren<unknown>): React.ReactNode => {
25+
if (!props.children) {
26+
return null;
27+
}
28+
29+
if (typeof props.children === 'function') {
30+
return (props.children as () => React.ReactNode)();
31+
}
32+
33+
// since Next.js >= 10 requires React ^16.6.0 we are allowed to return children like this here
34+
return props.children as React.ReactNode;
35+
};
36+
37+
/**
38+
* A passthrough error boundary wrapper for the server that doesn't depend on any react. Error boundaries don't catch
39+
* SSR errors so they should simply be a passthrough.
40+
*/
41+
export function withErrorBoundary<P extends Record<string, any>>(
42+
WrappedComponent: React.ComponentType<P>,
43+
): React.FC<P> {
44+
return WrappedComponent as React.FC<P>;
45+
}
46+
47+
/**
48+
* Just a passthrough since we're on the server and showing the report dialog on the server doesn't make any sense.
49+
*/
50+
export function showReportDialog(): void {
51+
return;
52+
}
2353

2454
const globalWithInjectedValues = global as typeof global & {
2555
__rewriteFramesDistDir__: string;

packages/react/src/errorboundary.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ReportDialogOptions, Scope} from '@sentry/browser';
1+
import type { ReportDialogOptions, Scope } from '@sentry/browser';
22
import { captureException, showReportDialog, withScope } from '@sentry/browser';
33
import { isError, logger } from '@sentry/utils';
44
import hoistNonReactStatics from 'hoist-non-react-statics';

0 commit comments

Comments
 (0)