Fix: Selective hydration causing incorrect thenable type passed to DevTools (#26275)

Selective hydration is implemented by suspending the current render
using a special internal opaque object. This is conceptually similar to
suspending with a thenable in userspace, but the opaque object should
not leak outside of the reconciler.

We were accidentally passing this object to DevTool's
markComponentSuspended function, which expects an actual thenable. This
happens in the error handling path (handleThrow).

The fix is to check for the exception reason before calling
markComponentSuspended. There was already a naive check in place, but it
didn't account for all possible enum values of the exception reason.

DiffTrain build for [41110021f2](https://github.com/facebook/react/commit/41110021f28100b16c11d6d9a248582c5bb6bc3c)
This commit is contained in:
acdlite
2023-03-01 16:44:34 +00:00
parent f091225e5c
commit 55dcf28607
28 changed files with 192 additions and 142 deletions
+1 -1
View File
@@ -1 +1 @@
67a61d5bd7f731f5eb37d148dfc4ae0515a8c934
41110021f28100b16c11d6d9a248582c5bb6bc3c
+1 -1
View File
@@ -1 +1 @@
67a61d5bd7f731f5eb37d148dfc4ae0515a8c934
41110021f28100b16c11d6d9a248582c5bb6bc3c
+1 -1
View File
@@ -27,7 +27,7 @@ if (
}
"use strict";
var ReactVersion = "18.3.0-www-classic-67a61d5bd-20230228";
var ReactVersion = "18.3.0-www-classic-41110021f-20230301";
// ATTENTION
// When adding new symbols to this file,
+1 -1
View File
@@ -27,7 +27,7 @@ if (
}
"use strict";
var ReactVersion = "18.3.0-www-modern-67a61d5bd-20230228";
var ReactVersion = "18.3.0-www-modern-41110021f-20230301";
// ATTENTION
// When adding new symbols to this file,
+1 -1
View File
@@ -646,4 +646,4 @@ exports.useSyncExternalStore = function (
);
};
exports.useTransition = useTransition;
exports.version = "18.3.0-www-classic-67a61d5bd-20230228";
exports.version = "18.3.0-www-classic-41110021f-20230301";
+1 -1
View File
@@ -638,4 +638,4 @@ exports.useSyncExternalStore = function (
);
};
exports.useTransition = useTransition;
exports.version = "18.3.0-www-modern-67a61d5bd-20230228";
exports.version = "18.3.0-www-modern-41110021f-20230301";
@@ -657,7 +657,7 @@ exports.useSyncExternalStore = function (
);
};
exports.useTransition = useTransition;
exports.version = "18.3.0-www-classic-67a61d5bd-20230228";
exports.version = "18.3.0-www-classic-41110021f-20230301";
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
@@ -649,7 +649,7 @@ exports.useSyncExternalStore = function (
);
};
exports.useTransition = useTransition;
exports.version = "18.3.0-www-modern-67a61d5bd-20230228";
exports.version = "18.3.0-www-modern-41110021f-20230301";
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
+23 -14
View File
@@ -69,7 +69,7 @@ function _assertThisInitialized(self) {
return self;
}
var ReactVersion = "18.3.0-www-classic-67a61d5bd-20230228";
var ReactVersion = "18.3.0-www-classic-41110021f-20230301";
var LegacyRoot = 0;
var ConcurrentRoot = 1;
@@ -24187,19 +24187,28 @@ function handleThrow(root, thrownValue) {
if (enableSchedulingProfiler) {
markComponentRenderStopped();
if (workInProgressSuspendedReason !== SuspendedOnError) {
var wakeable = thrownValue;
markComponentSuspended(
erroredWork,
wakeable,
workInProgressRootRenderLanes
);
} else {
markComponentErrored(
erroredWork,
thrownValue,
workInProgressRootRenderLanes
);
switch (workInProgressSuspendedReason) {
case SuspendedOnError: {
markComponentErrored(
erroredWork,
thrownValue,
workInProgressRootRenderLanes
);
break;
}
case SuspendedOnData:
case SuspendedOnImmediate:
case SuspendedOnDeprecatedThrowPromise:
case SuspendedAndReadyToUnwind: {
var wakeable = thrownValue;
markComponentSuspended(
erroredWork,
wakeable,
workInProgressRootRenderLanes
);
break;
}
}
}
}
+23 -14
View File
@@ -69,7 +69,7 @@ function _assertThisInitialized(self) {
return self;
}
var ReactVersion = "18.3.0-www-modern-67a61d5bd-20230228";
var ReactVersion = "18.3.0-www-modern-41110021f-20230301";
var LegacyRoot = 0;
var ConcurrentRoot = 1;
@@ -23847,19 +23847,28 @@ function handleThrow(root, thrownValue) {
if (enableSchedulingProfiler) {
markComponentRenderStopped();
if (workInProgressSuspendedReason !== SuspendedOnError) {
var wakeable = thrownValue;
markComponentSuspended(
erroredWork,
wakeable,
workInProgressRootRenderLanes
);
} else {
markComponentErrored(
erroredWork,
thrownValue,
workInProgressRootRenderLanes
);
switch (workInProgressSuspendedReason) {
case SuspendedOnError: {
markComponentErrored(
erroredWork,
thrownValue,
workInProgressRootRenderLanes
);
break;
}
case SuspendedOnData:
case SuspendedOnImmediate:
case SuspendedOnDeprecatedThrowPromise:
case SuspendedAndReadyToUnwind: {
var wakeable = thrownValue;
markComponentSuspended(
erroredWork,
wakeable,
workInProgressRootRenderLanes
);
break;
}
}
}
}
@@ -9780,7 +9780,7 @@ var slice = Array.prototype.slice,
return null;
},
bundleType: 0,
version: "18.3.0-www-classic-67a61d5bd-20230228",
version: "18.3.0-www-classic-41110021f-20230301",
rendererPackageName: "react-art"
};
var internals$jscomp$inline_1300 = {
@@ -9811,7 +9811,7 @@ var internals$jscomp$inline_1300 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-67a61d5bd-20230228"
reconcilerVersion: "18.3.0-next-41110021f-20230301"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1301 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -9445,7 +9445,7 @@ var slice = Array.prototype.slice,
return null;
},
bundleType: 0,
version: "18.3.0-www-modern-67a61d5bd-20230228",
version: "18.3.0-www-modern-41110021f-20230301",
rendererPackageName: "react-art"
};
var internals$jscomp$inline_1280 = {
@@ -9476,7 +9476,7 @@ var internals$jscomp$inline_1280 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-67a61d5bd-20230228"
reconcilerVersion: "18.3.0-next-41110021f-20230301"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1281 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
+23 -14
View File
@@ -38752,19 +38752,28 @@ function handleThrow(root, thrownValue) {
if (enableSchedulingProfiler) {
markComponentRenderStopped();
if (workInProgressSuspendedReason !== SuspendedOnError) {
var wakeable = thrownValue;
markComponentSuspended(
erroredWork,
wakeable,
workInProgressRootRenderLanes
);
} else {
markComponentErrored(
erroredWork,
thrownValue,
workInProgressRootRenderLanes
);
switch (workInProgressSuspendedReason) {
case SuspendedOnError: {
markComponentErrored(
erroredWork,
thrownValue,
workInProgressRootRenderLanes
);
break;
}
case SuspendedOnData:
case SuspendedOnImmediate:
case SuspendedOnDeprecatedThrowPromise:
case SuspendedAndReadyToUnwind: {
var wakeable = thrownValue;
markComponentSuspended(
erroredWork,
wakeable,
workInProgressRootRenderLanes
);
break;
}
}
}
}
@@ -42099,7 +42108,7 @@ function createFiberRoot(
return root;
}
var ReactVersion = "18.3.0-www-classic-67a61d5bd-20230228";
var ReactVersion = "18.3.0-www-classic-41110021f-20230301";
function createPortal$1(
children,
+23 -14
View File
@@ -38356,19 +38356,28 @@ function handleThrow(root, thrownValue) {
if (enableSchedulingProfiler) {
markComponentRenderStopped();
if (workInProgressSuspendedReason !== SuspendedOnError) {
var wakeable = thrownValue;
markComponentSuspended(
erroredWork,
wakeable,
workInProgressRootRenderLanes
);
} else {
markComponentErrored(
erroredWork,
thrownValue,
workInProgressRootRenderLanes
);
switch (workInProgressSuspendedReason) {
case SuspendedOnError: {
markComponentErrored(
erroredWork,
thrownValue,
workInProgressRootRenderLanes
);
break;
}
case SuspendedOnData:
case SuspendedOnImmediate:
case SuspendedOnDeprecatedThrowPromise:
case SuspendedAndReadyToUnwind: {
var wakeable = thrownValue;
markComponentSuspended(
erroredWork,
wakeable,
workInProgressRootRenderLanes
);
break;
}
}
}
}
@@ -41703,7 +41712,7 @@ function createFiberRoot(
return root;
}
var ReactVersion = "18.3.0-www-modern-67a61d5bd-20230228";
var ReactVersion = "18.3.0-www-modern-41110021f-20230301";
function createPortal$1(
children,
@@ -15490,7 +15490,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1741 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-classic-67a61d5bd-20230228",
version: "18.3.0-www-classic-41110021f-20230301",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2108 = {
@@ -15520,7 +15520,7 @@ var internals$jscomp$inline_2108 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-67a61d5bd-20230228"
reconcilerVersion: "18.3.0-next-41110021f-20230301"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2109 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -15776,4 +15776,4 @@ exports.unstable_renderSubtreeIntoContainer = function (
);
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-next-67a61d5bd-20230228";
exports.version = "18.3.0-next-41110021f-20230301";
@@ -15019,7 +15019,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1700 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-modern-67a61d5bd-20230228",
version: "18.3.0-www-modern-41110021f-20230301",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2072 = {
@@ -15050,7 +15050,7 @@ var internals$jscomp$inline_2072 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-67a61d5bd-20230228"
reconcilerVersion: "18.3.0-next-41110021f-20230301"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2073 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -15235,4 +15235,4 @@ exports.unstable_flushControlled = function (fn) {
}
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-next-67a61d5bd-20230228";
exports.version = "18.3.0-next-41110021f-20230301";
@@ -13996,30 +13996,37 @@ function handleThrow(root, thrownValue) {
: 1;
workInProgressThrownValue = thrownValue;
root = workInProgress;
null === root
? ((workInProgressRootExitStatus = 1),
(workInProgressRootFatalError = thrownValue))
: (root.mode & 2 && stopProfilerTimerIfRunningAndRecordDelta(root, !0),
enableSchedulingProfiler &&
(markComponentRenderStopped(),
1 !== workInProgressSuspendedReason
? enableSchedulingProfiler &&
null !== injectedProfilingHooks &&
"function" ===
typeof injectedProfilingHooks.markComponentSuspended &&
injectedProfilingHooks.markComponentSuspended(
root,
thrownValue,
workInProgressRootRenderLanes
)
: enableSchedulingProfiler &&
null !== injectedProfilingHooks &&
"function" === typeof injectedProfilingHooks.markComponentErrored &&
injectedProfilingHooks.markComponentErrored(
root,
thrownValue,
workInProgressRootRenderLanes
)));
if (null === root)
(workInProgressRootExitStatus = 1),
(workInProgressRootFatalError = thrownValue);
else if (
(root.mode & 2 && stopProfilerTimerIfRunningAndRecordDelta(root, !0),
enableSchedulingProfiler)
)
switch ((markComponentRenderStopped(), workInProgressSuspendedReason)) {
case 1:
enableSchedulingProfiler &&
null !== injectedProfilingHooks &&
"function" === typeof injectedProfilingHooks.markComponentErrored &&
injectedProfilingHooks.markComponentErrored(
root,
thrownValue,
workInProgressRootRenderLanes
);
break;
case 2:
case 3:
case 4:
case 5:
enableSchedulingProfiler &&
null !== injectedProfilingHooks &&
"function" === typeof injectedProfilingHooks.markComponentSuspended &&
injectedProfilingHooks.markComponentSuspended(
root,
thrownValue,
workInProgressRootRenderLanes
);
}
}
function shouldAttemptToSuspendUntilDataResolves() {
if (
@@ -16260,7 +16267,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1821 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-classic-67a61d5bd-20230228",
version: "18.3.0-www-classic-41110021f-20230301",
rendererPackageName: "react-dom"
};
(function (internals) {
@@ -16304,7 +16311,7 @@ var devToolsConfig$jscomp$inline_1821 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-67a61d5bd-20230228"
reconcilerVersion: "18.3.0-next-41110021f-20230301"
});
assign(Internals, {
ReactBrowserEventEmitter: {
@@ -16547,7 +16554,7 @@ exports.unstable_renderSubtreeIntoContainer = function (
);
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-next-67a61d5bd-20230228";
exports.version = "18.3.0-next-41110021f-20230301";
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
@@ -13731,30 +13731,37 @@ function handleThrow(root, thrownValue) {
: 1;
workInProgressThrownValue = thrownValue;
root = workInProgress;
null === root
? ((workInProgressRootExitStatus = 1),
(workInProgressRootFatalError = thrownValue))
: (root.mode & 2 && stopProfilerTimerIfRunningAndRecordDelta(root, !0),
enableSchedulingProfiler &&
(markComponentRenderStopped(),
1 !== workInProgressSuspendedReason
? enableSchedulingProfiler &&
null !== injectedProfilingHooks &&
"function" ===
typeof injectedProfilingHooks.markComponentSuspended &&
injectedProfilingHooks.markComponentSuspended(
root,
thrownValue,
workInProgressRootRenderLanes
)
: enableSchedulingProfiler &&
null !== injectedProfilingHooks &&
"function" === typeof injectedProfilingHooks.markComponentErrored &&
injectedProfilingHooks.markComponentErrored(
root,
thrownValue,
workInProgressRootRenderLanes
)));
if (null === root)
(workInProgressRootExitStatus = 1),
(workInProgressRootFatalError = thrownValue);
else if (
(root.mode & 2 && stopProfilerTimerIfRunningAndRecordDelta(root, !0),
enableSchedulingProfiler)
)
switch ((markComponentRenderStopped(), workInProgressSuspendedReason)) {
case 1:
enableSchedulingProfiler &&
null !== injectedProfilingHooks &&
"function" === typeof injectedProfilingHooks.markComponentErrored &&
injectedProfilingHooks.markComponentErrored(
root,
thrownValue,
workInProgressRootRenderLanes
);
break;
case 2:
case 3:
case 4:
case 5:
enableSchedulingProfiler &&
null !== injectedProfilingHooks &&
"function" === typeof injectedProfilingHooks.markComponentSuspended &&
injectedProfilingHooks.markComponentSuspended(
root,
thrownValue,
workInProgressRootRenderLanes
);
}
}
function shouldAttemptToSuspendUntilDataResolves() {
if (
@@ -15779,7 +15786,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1780 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-modern-67a61d5bd-20230228",
version: "18.3.0-www-modern-41110021f-20230301",
rendererPackageName: "react-dom"
};
(function (internals) {
@@ -15824,7 +15831,7 @@ var devToolsConfig$jscomp$inline_1780 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-67a61d5bd-20230228"
reconcilerVersion: "18.3.0-next-41110021f-20230301"
});
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
exports.createPortal = function (children, container) {
@@ -15996,7 +16003,7 @@ exports.unstable_flushControlled = function (fn) {
}
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-next-67a61d5bd-20230228";
exports.version = "18.3.0-next-41110021f-20230301";
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
@@ -19,7 +19,7 @@ if (__DEV__) {
var React = require("react");
var ReactDOM = require("react-dom");
var ReactVersion = "18.3.0-www-classic-67a61d5bd-20230228";
var ReactVersion = "18.3.0-www-classic-41110021f-20230301";
// This refers to a WWW module.
var warningWWW = require("warning");
@@ -19,7 +19,7 @@ if (__DEV__) {
var React = require("react");
var ReactDOM = require("react-dom");
var ReactVersion = "18.3.0-www-modern-67a61d5bd-20230228";
var ReactVersion = "18.3.0-www-modern-41110021f-20230301";
// This refers to a WWW module.
var warningWWW = require("warning");
@@ -3721,4 +3721,4 @@ exports.renderToString = function (children, options) {
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
);
};
exports.version = "18.3.0-www-classic-67a61d5bd-20230228";
exports.version = "18.3.0-www-classic-41110021f-20230301";
@@ -3619,4 +3619,4 @@ exports.renderToString = function (children, options) {
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
);
};
exports.version = "18.3.0-www-modern-67a61d5bd-20230228";
exports.version = "18.3.0-www-modern-41110021f-20230301";
@@ -31237,7 +31237,7 @@ function createFiberRoot(
return root;
}
var ReactVersion = "18.3.0-www-classic-67a61d5bd-20230228";
var ReactVersion = "18.3.0-www-classic-41110021f-20230301";
function createPortal$1(
children,
@@ -37728,7 +37728,7 @@ function createFiberRoot(
return root;
}
var ReactVersion = "18.3.0-www-modern-67a61d5bd-20230228";
var ReactVersion = "18.3.0-www-modern-41110021f-20230301";
function createPortal$1(
children,
@@ -11521,7 +11521,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1535 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-classic-67a61d5bd-20230228",
version: "18.3.0-www-classic-41110021f-20230301",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2058 = {
@@ -11551,7 +11551,7 @@ var internals$jscomp$inline_2058 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-67a61d5bd-20230228"
reconcilerVersion: "18.3.0-next-41110021f-20230301"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2059 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -14782,4 +14782,4 @@ exports.unstable_renderSubtreeIntoContainer = function (
);
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-next-67a61d5bd-20230228";
exports.version = "18.3.0-next-41110021f-20230301";
@@ -13881,7 +13881,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1652 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-modern-67a61d5bd-20230228",
version: "18.3.0-www-modern-41110021f-20230301",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2032 = {
@@ -13912,7 +13912,7 @@ var internals$jscomp$inline_2032 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-67a61d5bd-20230228"
reconcilerVersion: "18.3.0-next-41110021f-20230301"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2033 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -14240,4 +14240,4 @@ exports.unstable_flushControlled = function (fn) {
}
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-next-67a61d5bd-20230228";
exports.version = "18.3.0-next-41110021f-20230301";
@@ -23753,7 +23753,7 @@ function createFiberRoot(
return root;
}
var ReactVersion = "18.3.0-www-classic-67a61d5bd-20230228";
var ReactVersion = "18.3.0-www-classic-41110021f-20230301";
// Might add PROFILE later.
@@ -23753,7 +23753,7 @@ function createFiberRoot(
return root;
}
var ReactVersion = "18.3.0-www-modern-67a61d5bd-20230228";
var ReactVersion = "18.3.0-www-modern-41110021f-20230301";
// Might add PROFILE later.