Skip to content

Commit 04f6178

Browse files
committed
refactor this a little bit more
1 parent df17b72 commit 04f6178

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

docs/migration/v8-to-v9.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ Older Typescript versions _may_ still work, but we will not test them anymore an
128128

129129
### `@sentry/react`
130130

131-
The `componentStack` field in the `ErrorBoundary` component is now typed as `string | undefined` instead of `string | null | undefined`. This more closely matches the actual behavior of React, which always returns a `string` whenever a component stack is available. `undefined` is only returned if no error has been caught by the error boundary.
131+
The `componentStack` field in the `ErrorBoundary` component is now typed as `string` instead of `string | null | undefined` for the `onError` and `onReset` lifecycle methods. This more closely matches the actual behavior of React, which always returns a `string` whenever a component stack is available.
132+
133+
In the `onUnmount` lifecycle method, the `componentStack` field is now typed as `string | null`. The `componentStack` is `null` when no error has been thrown at time of unmount.
132134

133135
### Uncategorized (TODO)
134136

packages/react/src/errorboundary.tsx

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ export type FallbackRender = (errorData: {
1717
resetError(): void;
1818
}) => React.ReactElement;
1919

20+
type OnUnmountType = {
21+
(error: null, componentStack: null, eventId: null): void;
22+
(error: unknown, componentStack: string, eventId: string): void;
23+
};
24+
2025
export type ErrorBoundaryProps = {
2126
children?: React.ReactNode | (() => React.ReactNode);
2227
/** If a Sentry report dialog should be rendered on error */
@@ -45,10 +50,18 @@ export type ErrorBoundaryProps = {
4550
onError?: ((error: unknown, componentStack: string, eventId: string) => void) | undefined;
4651
/** Called on componentDidMount() */
4752
onMount?: (() => void) | undefined;
48-
/** Called if resetError() is called from the fallback render props function */
49-
onReset?: ((error: unknown, componentStack: string | null, eventId: string | null) => void) | undefined;
50-
/** Called on componentWillUnmount() */
51-
onUnmount?: ((error: unknown, componentStack: string | null, eventId: string | null) => void) | undefined;
53+
/**
54+
* Called when the error boundary resets due to a reset call from the
55+
* fallback render props function.
56+
*/
57+
onReset?: ((error: unknown, componentStack: string, eventId: string) => void) | undefined;
58+
/**
59+
* Called on componentWillUnmount() with the error, componentStack, and eventId.
60+
*
61+
* If the error boundary never encountered an error, the error
62+
* componentStack, and eventId will be null.
63+
*/
64+
onUnmount?: OnUnmountType | undefined;
5265
/** Called before the error is captured by Sentry, allows for you to add tags or context using the scope */
5366
beforeCapture?: ((scope: Scope, error: unknown, componentStack: string) => void) | undefined;
5467
};
@@ -140,7 +153,15 @@ class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundarySta
140153
const { error, componentStack, eventId } = this.state;
141154
const { onUnmount } = this.props;
142155
if (onUnmount) {
143-
onUnmount(error, componentStack, eventId);
156+
if (this.state === INITIAL_STATE) {
157+
// If the error boundary never encountered an error, call onUnmount with null values
158+
onUnmount(null, null, null);
159+
} else {
160+
// `componentStack` and `eventId` are guaranteed to be non-null here because `onUnmount` is only called
161+
// when the error boundary has already encountered an error.
162+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
163+
onUnmount(error, componentStack!, eventId!);
164+
}
144165
}
145166

146167
if (this._cleanupHook) {
@@ -153,7 +174,10 @@ class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundarySta
153174
const { onReset } = this.props;
154175
const { error, componentStack, eventId } = this.state;
155176
if (onReset) {
156-
onReset(error, componentStack, eventId);
177+
// `componentStack` and `eventId` are guaranteed to be non-null here because `onReset` is only called
178+
// when the error boundary has already encountered an error.
179+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
180+
onReset(error, componentStack!, eventId!);
157181
}
158182
this.setState(INITIAL_STATE);
159183
}

0 commit comments

Comments
 (0)