Skip to content

Commit c44665e

Browse files
authored
Fix bug when fatal error is thrown as a result of batch.commit (#12480)
Fixes #12474
1 parent 268a3f6 commit c44665e

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

packages/react-dom/src/__tests__/ReactDOMRoot-test.internal.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,4 +320,14 @@ describe('ReactDOMRoot', () => {
320320
flush();
321321
expect(container.textContent).toEqual('1');
322322
});
323+
324+
it('handles fatal errors triggered by batch.commit()', () => {
325+
const root = ReactDOM.createRoot(container);
326+
const batch = root.createBatch();
327+
const InvalidType = undefined;
328+
expect(() => batch.render(<InvalidType />)).toWarnDev([
329+
'React.createElement: type is invalid',
330+
]);
331+
expect(() => batch.commit()).toThrow('Element type is invalid');
332+
});
323333
});

packages/react-reconciler/src/ReactFiberScheduler.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,12 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
932932
const sourceFiber: Fiber = nextUnitOfWork;
933933
let returnFiber = sourceFiber.return;
934934
if (returnFiber === null) {
935-
// This is a fatal error.
935+
// This is the root. The root could capture its own errors. However,
936+
// we don't know if it errors before or after we pushed the host
937+
// context. This information is needed to avoid a stack mismatch.
938+
// Because we're not sure, treat this as a fatal error. We could track
939+
// which phase it fails in, but doesn't seem worth it. At least
940+
// for now.
936941
didFatal = true;
937942
onUncaughtError(thrownValue);
938943
break;
@@ -1492,6 +1497,8 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
14921497
// Perform work on root as if the given expiration time is the current time.
14931498
// This has the effect of synchronously flushing all work up to and
14941499
// including the given time.
1500+
nextFlushedRoot = root;
1501+
nextFlushedExpirationTime = expirationTime;
14951502
performWorkOnRoot(root, expirationTime, false);
14961503
finishRendering();
14971504
}

0 commit comments

Comments
 (0)