Skip to content

Commit 1c71e8e

Browse files
authored
fix(react): Set handled value in ErrorBoundary depending on fallback [v7] (#11037)
Backport of #10989
1 parent c6e03a3 commit 1c71e8e

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed

packages/react/src/errorboundary.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,9 @@ class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundarySta
147147
captureContext: {
148148
contexts: { react: { componentStack } },
149149
},
150-
mechanism: { handled: false },
150+
// If users provide a fallback component we can assume they are handling the error.
151+
// Therefore, we set the mechanism depending on the presence of the fallback prop.
152+
mechanism: { handled: !!this.props.fallback },
151153
});
152154

153155
if (onError) {

packages/react/test/errorboundary.test.tsx

+46-4
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ describe('ErrorBoundary', () => {
242242
captureContext: {
243243
contexts: { react: { componentStack: expect.any(String) } },
244244
},
245-
mechanism: { handled: false },
245+
mechanism: { handled: true },
246246
});
247247

248248
expect(mockOnError.mock.calls[0][0]).toEqual(mockCaptureException.mock.calls[0][0]);
@@ -300,7 +300,7 @@ describe('ErrorBoundary', () => {
300300
captureContext: {
301301
contexts: { react: { componentStack: expect.any(String) } },
302302
},
303-
mechanism: { handled: false },
303+
mechanism: { handled: true },
304304
});
305305

306306
// Check if error.cause -> react component stack
@@ -339,7 +339,7 @@ describe('ErrorBoundary', () => {
339339
captureContext: {
340340
contexts: { react: { componentStack: expect.any(String) } },
341341
},
342-
mechanism: { handled: false },
342+
mechanism: { handled: true },
343343
});
344344

345345
expect(mockOnError.mock.calls[0][0]).toEqual(mockCaptureException.mock.calls[0][0]);
@@ -383,7 +383,7 @@ describe('ErrorBoundary', () => {
383383
captureContext: {
384384
contexts: { react: { componentStack: expect.any(String) } },
385385
},
386-
mechanism: { handled: false },
386+
mechanism: { handled: true },
387387
});
388388

389389
expect(mockOnError.mock.calls[0][0]).toEqual(mockCaptureException.mock.calls[0][0]);
@@ -515,6 +515,48 @@ describe('ErrorBoundary', () => {
515515
expect(mockOnReset).toHaveBeenCalledTimes(1);
516516
expect(mockOnReset).toHaveBeenCalledWith(expect.any(Error), expect.any(String), expect.any(String));
517517
});
518+
519+
it('sets `handled: true` when a fallback is provided', async () => {
520+
render(
521+
<TestApp fallback={({ resetError }) => <button data-testid="reset" onClick={resetError} />}>
522+
<h1>children</h1>
523+
</TestApp>,
524+
);
525+
526+
expect(mockCaptureException).toHaveBeenCalledTimes(0);
527+
528+
const btn = screen.getByTestId('errorBtn');
529+
fireEvent.click(btn);
530+
531+
expect(mockCaptureException).toHaveBeenCalledTimes(1);
532+
expect(mockCaptureException).toHaveBeenLastCalledWith(expect.any(Object), {
533+
captureContext: {
534+
contexts: { react: { componentStack: expect.any(String) } },
535+
},
536+
mechanism: { handled: true },
537+
});
538+
});
539+
540+
it('sets `handled: false` when no fallback is provided', async () => {
541+
render(
542+
<TestApp>
543+
<h1>children</h1>
544+
</TestApp>,
545+
);
546+
547+
expect(mockCaptureException).toHaveBeenCalledTimes(0);
548+
549+
const btn = screen.getByTestId('errorBtn');
550+
fireEvent.click(btn);
551+
552+
expect(mockCaptureException).toHaveBeenCalledTimes(1);
553+
expect(mockCaptureException).toHaveBeenLastCalledWith(expect.any(Object), {
554+
captureContext: {
555+
contexts: { react: { componentStack: expect.any(String) } },
556+
},
557+
mechanism: { handled: false },
558+
});
559+
});
518560
});
519561
});
520562

0 commit comments

Comments
 (0)