diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseCallback-test.internal.js b/packages/react-reconciler/src/__tests__/ReactSuspenseCallback-test.internal.js
index 8a6997107b47b..77daba9d97fcf 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspenseCallback-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspenseCallback-test.internal.js
@@ -238,4 +238,71 @@ describe('ReactSuspense', () => {
expect(ops1).toEqual([]);
expect(ops2).toEqual([]);
});
+
+ if (__DEV__) {
+ it('regression test for #16215 that relies on implementation details', async () => {
+ // Regression test for https://github.com/facebook/react/pull/16215.
+ // The bug only happens if there's an error earlier in the commit phase.
+ // The first error is the one that gets thrown, so to observe the later
+ // error, I've mocked the ReactErrorUtils module.
+ //
+ // If this test starts failing because the implementation details change,
+ // you can probably just delete it. It's not worth the hassle.
+ jest.resetModules();
+
+ let errors = [];
+ let hasCaughtError = false;
+ jest.mock('shared/ReactErrorUtils', () => ({
+ invokeGuardedCallback(name, fn, context, ...args) {
+ try {
+ return fn.call(context, ...args);
+ } catch (error) {
+ hasCaughtError = true;
+ errors.push(error);
+ }
+ },
+ hasCaughtError() {
+ return hasCaughtError;
+ },
+ clearCaughtError() {
+ hasCaughtError = false;
+ return errors[errors.length - 1];
+ },
+ }));
+
+ ReactFeatureFlags = require('shared/ReactFeatureFlags');
+ ReactFeatureFlags.enableSuspenseCallback = true;
+
+ React = require('react');
+ ReactNoop = require('react-noop-renderer');
+ Scheduler = require('scheduler');
+
+ const {useEffect} = React;
+ const {PromiseComp} = createThenable();
+ function App() {
+ useEffect(() => {
+ Scheduler.unstable_yieldValue('Passive Effect');
+ });
+ return (
+ {
+ throw Error('Oops!');
+ }}
+ fallback="Loading...">
+
+
+ );
+ }
+ const root = ReactNoop.createRoot();
+ await ReactNoop.act(async () => {
+ root.render();
+ expect(Scheduler).toFlushAndThrow('Oops!');
+ });
+
+ // Should have only received a single error. Before the bug fix, there was
+ // also a second error related to the Suspense update queue.
+ expect(errors.length).toBe(1);
+ expect(errors[0].message).toEqual('Oops!');
+ });
+ }
});