Use a Wrapper Error for onRecoverableError with a "cause" Field for the real Error (#28736)

We basically have four kinds of recoverable errors:

- Hydration mismatches.
- Server errored but client didn't.
- Hydration render errored but client render didn't (in Root or Suspense
boundary).
- Concurrent render errored but synchronous render didn't.

For the first three we log an additional error that the root or Suspense
boundary didn't error. This provides some context about what happened.
However, the problem is that for hydration mismatches that's unnecessary
extra context that is confusing. We also don't log any additional
context for concurrent render errors that could recover. This used to be
the only recoverable error so it didn't need extra context but now we
need to distinguish them. When we log these to `reportError` it's
confusing to just see the error because you didn't see anything error on
the page. It's also hard to group them together as one.

In this PR, I remove the unnecessary context for hydration mismatches.

For hydration and concurrent errors, I now wrap them in an error that
describes that what happened but then use the new `cause` field to link
the original error so we can keep that as the cause. The error that
happened was that hydration client rendered or you deopted to sync
render, the cause of that error is some other error.

For server errors, we control the Error object so I already had added
some context to that error object's message. Since we hide the message
in prod, it's nice not to have the raw message in DEV neither. We could
potentially split these into two errors for parity though.

DiffTrain build for [6090cab099](https://github.com/facebook/react/commit/6090cab099a8f7f373e04c7eb2937425a8f80f80)
This commit is contained in:
sebmarkbage
2024-04-04 01:58:18 +00:00
parent 2d934393d1
commit e0fc90e076
17 changed files with 5256 additions and 5135 deletions
+1 -1
View File
@@ -1 +1 @@
583eb6770d56e9793d3660bd9c6782fdebc93729
6090cab099a8f7f373e04c7eb2937425a8f80f80
+429 -435
View File
@@ -66,7 +66,7 @@ if (__DEV__) {
return self;
}
var ReactVersion = "19.0.0-www-classic-fce3a147";
var ReactVersion = "19.0.0-www-classic-086110c8";
var LegacyRoot = 0;
var ConcurrentRoot = 1;
@@ -3588,6 +3588,394 @@ if (__DEV__) {
}
}
var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher;
var prefix;
function describeBuiltInComponentFrame(name, ownerFn) {
{
if (prefix === undefined) {
// Extract the VM specific prefix used by each line.
try {
throw Error();
} catch (x) {
var match = x.stack.trim().match(/\n( *(at )?)/);
prefix = (match && match[1]) || "";
}
} // We use the prefix to ensure our stacks line up with native stack frames.
return "\n" + prefix + name;
}
}
function describeDebugInfoFrame(name, env) {
return describeBuiltInComponentFrame(
name + (env ? " (" + env + ")" : "")
);
}
var reentry = false;
var componentFrameCache;
{
var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map;
componentFrameCache = new PossiblyWeakMap$1();
}
/**
* Leverages native browser/VM stack frames to get proper details (e.g.
* filename, line + col number) for a single component in a component stack. We
* do this by:
* (1) throwing and catching an error in the function - this will be our
* control error.
* (2) calling the component which will eventually throw an error that we'll
* catch - this will be our sample error.
* (3) diffing the control and sample error stacks to find the stack frame
* which represents our component.
*/
function describeNativeComponentFrame(fn, construct) {
// If something asked for a stack inside a fake render, it should get ignored.
if (!fn || reentry) {
return "";
}
{
var frame = componentFrameCache.get(fn);
if (frame !== undefined) {
return frame;
}
}
reentry = true;
var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe[incompatible-type] It does accept undefined.
Error.prepareStackTrace = undefined;
var previousDispatcher;
{
previousDispatcher = ReactCurrentDispatcher$2.current; // Set the dispatcher in DEV because this might be call in the render function
// for warnings.
ReactCurrentDispatcher$2.current = null;
disableLogs();
}
/**
* Finding a common stack frame between sample and control errors can be
* tricky given the different types and levels of stack trace truncation from
* different JS VMs. So instead we'll attempt to control what that common
* frame should be through this object method:
* Having both the sample and control errors be in the function under the
* `DescribeNativeComponentFrameRoot` property, + setting the `name` and
* `displayName` properties of the function ensures that a stack
* frame exists that has the method name `DescribeNativeComponentFrameRoot` in
* it for both control and sample stacks.
*/
var RunInRootFrame = {
DetermineComponentFrameRoot: function () {
var control;
try {
// This should throw.
if (construct) {
// Something should be setting the props in the constructor.
var Fake = function () {
throw Error();
}; // $FlowFixMe[prop-missing]
Object.defineProperty(Fake.prototype, "props", {
set: function () {
// We use a throwing setter instead of frozen or non-writable props
// because that won't throw in a non-strict mode function.
throw Error();
}
});
if (typeof Reflect === "object" && Reflect.construct) {
// We construct a different control for this case to include any extra
// frames added by the construct call.
try {
Reflect.construct(Fake, []);
} catch (x) {
control = x;
}
Reflect.construct(fn, [], Fake);
} else {
try {
Fake.call();
} catch (x) {
control = x;
} // $FlowFixMe[prop-missing] found when upgrading Flow
fn.call(Fake.prototype);
}
} else {
try {
throw Error();
} catch (x) {
control = x;
} // TODO(luna): This will currently only throw if the function component
// tries to access React/ReactDOM/props. We should probably make this throw
// in simple components too
var maybePromise = fn(); // If the function component returns a promise, it's likely an async
// component, which we don't yet support. Attach a noop catch handler to
// silence the error.
// TODO: Implement component stacks for async client components?
if (maybePromise && typeof maybePromise.catch === "function") {
maybePromise.catch(function () {});
}
}
} catch (sample) {
// This is inlined manually because closure doesn't do it for us.
if (sample && control && typeof sample.stack === "string") {
return [sample.stack, control.stack];
}
}
return [null, null];
}
}; // $FlowFixMe[prop-missing]
RunInRootFrame.DetermineComponentFrameRoot.displayName =
"DetermineComponentFrameRoot";
var namePropDescriptor = Object.getOwnPropertyDescriptor(
RunInRootFrame.DetermineComponentFrameRoot,
"name"
); // Before ES6, the `name` property was not configurable.
if (namePropDescriptor && namePropDescriptor.configurable) {
// V8 utilizes a function's `name` property when generating a stack trace.
Object.defineProperty(
RunInRootFrame.DetermineComponentFrameRoot, // Configurable properties can be updated even if its writable descriptor
// is set to `false`.
// $FlowFixMe[cannot-write]
"name",
{
value: "DetermineComponentFrameRoot"
}
);
}
try {
var _RunInRootFrame$Deter =
RunInRootFrame.DetermineComponentFrameRoot(),
sampleStack = _RunInRootFrame$Deter[0],
controlStack = _RunInRootFrame$Deter[1];
if (sampleStack && controlStack) {
// This extracts the first frame from the sample that isn't also in the control.
// Skipping one frame that we assume is the frame that calls the two.
var sampleLines = sampleStack.split("\n");
var controlLines = controlStack.split("\n");
var s = 0;
var c = 0;
while (
s < sampleLines.length &&
!sampleLines[s].includes("DetermineComponentFrameRoot")
) {
s++;
}
while (
c < controlLines.length &&
!controlLines[c].includes("DetermineComponentFrameRoot")
) {
c++;
} // We couldn't find our intentionally injected common root frame, attempt
// to find another common root frame by search from the bottom of the
// control stack...
if (s === sampleLines.length || c === controlLines.length) {
s = sampleLines.length - 1;
c = controlLines.length - 1;
while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
// We expect at least one stack frame to be shared.
// Typically this will be the root most one. However, stack frames may be
// cut off due to maximum stack limits. In this case, one maybe cut off
// earlier than the other. We assume that the sample is longer or the same
// and there for cut off earlier. So we should find the root most frame in
// the sample somewhere in the control.
c--;
}
}
for (; s >= 1 && c >= 0; s--, c--) {
// Next we find the first one that isn't the same which should be the
// frame that called our sample function and the control.
if (sampleLines[s] !== controlLines[c]) {
// In V8, the first line is describing the message but other VMs don't.
// If we're about to return the first line, and the control is also on the same
// line, that's a pretty good indicator that our sample threw at same line as
// the control. I.e. before we entered the sample frame. So we ignore this result.
// This can happen if you passed a class to function component, or non-function.
if (s !== 1 || c !== 1) {
do {
s--;
c--; // We may still have similar intermediate frames from the construct call.
// The next one that isn't the same should be our match though.
if (c < 0 || sampleLines[s] !== controlLines[c]) {
// V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
var _frame =
"\n" + sampleLines[s].replace(" at new ", " at "); // If our component frame is labeled "<anonymous>"
// but we have a user-provided "displayName"
// splice it in to make the stack more readable.
if (fn.displayName && _frame.includes("<anonymous>")) {
_frame = _frame.replace("<anonymous>", fn.displayName);
}
if (true) {
if (typeof fn === "function") {
componentFrameCache.set(fn, _frame);
}
} // Return the line we found.
return _frame;
}
} while (s >= 1 && c >= 0);
}
break;
}
}
}
} finally {
reentry = false;
{
ReactCurrentDispatcher$2.current = previousDispatcher;
reenableLogs();
}
Error.prepareStackTrace = previousPrepareStackTrace;
} // Fallback to just using the name if we couldn't make it throw.
var name = fn ? fn.displayName || fn.name : "";
var syntheticFrame = name ? describeBuiltInComponentFrame(name) : "";
{
if (typeof fn === "function") {
componentFrameCache.set(fn, syntheticFrame);
}
}
return syntheticFrame;
}
function describeClassComponentFrame(ctor, ownerFn) {
{
return describeNativeComponentFrame(ctor, true);
}
}
function describeFunctionComponentFrame(fn, ownerFn) {
{
return describeNativeComponentFrame(fn, false);
}
}
function describeFiber(fiber) {
switch (fiber.tag) {
case HostHoistable:
case HostSingleton:
case HostComponent:
return describeBuiltInComponentFrame(fiber.type);
case LazyComponent:
return describeBuiltInComponentFrame("Lazy");
case SuspenseComponent:
return describeBuiltInComponentFrame("Suspense");
case SuspenseListComponent:
return describeBuiltInComponentFrame("SuspenseList");
case FunctionComponent:
case SimpleMemoComponent:
return describeFunctionComponentFrame(fiber.type);
case ForwardRef:
return describeFunctionComponentFrame(fiber.type.render);
case ClassComponent:
return describeClassComponentFrame(fiber.type);
default:
return "";
}
}
function getStackByFiberInDevAndProd(workInProgress) {
try {
var info = "";
var node = workInProgress;
do {
info += describeFiber(node);
if (true) {
// Add any Server Component stack frames in reverse order.
var debugInfo = node._debugInfo;
if (debugInfo) {
for (var i = debugInfo.length - 1; i >= 0; i--) {
var entry = debugInfo[i];
if (typeof entry.name === "string") {
info += describeDebugInfoFrame(entry.name, entry.env);
}
}
}
} // $FlowFixMe[incompatible-type] we bail out when we get a null
node = node.return;
} while (node);
return info;
} catch (x) {
return "\nError generating stack: " + x.message + "\n" + x.stack;
}
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
var contextStackCursor = createCursor(null);
var contextFiberStackCursor = createCursor(null);
var rootInstanceStackCursor = createCursor(null); // Represents the nearest host transition provider (in React DOM, a <form />)
@@ -5816,357 +6204,6 @@ if (__DEV__) {
return true;
}
var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher;
var prefix;
function describeBuiltInComponentFrame(name, ownerFn) {
{
if (prefix === undefined) {
// Extract the VM specific prefix used by each line.
try {
throw Error();
} catch (x) {
var match = x.stack.trim().match(/\n( *(at )?)/);
prefix = (match && match[1]) || "";
}
} // We use the prefix to ensure our stacks line up with native stack frames.
return "\n" + prefix + name;
}
}
function describeDebugInfoFrame(name, env) {
return describeBuiltInComponentFrame(
name + (env ? " (" + env + ")" : "")
);
}
var reentry = false;
var componentFrameCache;
{
var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map;
componentFrameCache = new PossiblyWeakMap$1();
}
/**
* Leverages native browser/VM stack frames to get proper details (e.g.
* filename, line + col number) for a single component in a component stack. We
* do this by:
* (1) throwing and catching an error in the function - this will be our
* control error.
* (2) calling the component which will eventually throw an error that we'll
* catch - this will be our sample error.
* (3) diffing the control and sample error stacks to find the stack frame
* which represents our component.
*/
function describeNativeComponentFrame(fn, construct) {
// If something asked for a stack inside a fake render, it should get ignored.
if (!fn || reentry) {
return "";
}
{
var frame = componentFrameCache.get(fn);
if (frame !== undefined) {
return frame;
}
}
reentry = true;
var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe[incompatible-type] It does accept undefined.
Error.prepareStackTrace = undefined;
var previousDispatcher;
{
previousDispatcher = ReactCurrentDispatcher$2.current; // Set the dispatcher in DEV because this might be call in the render function
// for warnings.
ReactCurrentDispatcher$2.current = null;
disableLogs();
}
/**
* Finding a common stack frame between sample and control errors can be
* tricky given the different types and levels of stack trace truncation from
* different JS VMs. So instead we'll attempt to control what that common
* frame should be through this object method:
* Having both the sample and control errors be in the function under the
* `DescribeNativeComponentFrameRoot` property, + setting the `name` and
* `displayName` properties of the function ensures that a stack
* frame exists that has the method name `DescribeNativeComponentFrameRoot` in
* it for both control and sample stacks.
*/
var RunInRootFrame = {
DetermineComponentFrameRoot: function () {
var control;
try {
// This should throw.
if (construct) {
// Something should be setting the props in the constructor.
var Fake = function () {
throw Error();
}; // $FlowFixMe[prop-missing]
Object.defineProperty(Fake.prototype, "props", {
set: function () {
// We use a throwing setter instead of frozen or non-writable props
// because that won't throw in a non-strict mode function.
throw Error();
}
});
if (typeof Reflect === "object" && Reflect.construct) {
// We construct a different control for this case to include any extra
// frames added by the construct call.
try {
Reflect.construct(Fake, []);
} catch (x) {
control = x;
}
Reflect.construct(fn, [], Fake);
} else {
try {
Fake.call();
} catch (x) {
control = x;
} // $FlowFixMe[prop-missing] found when upgrading Flow
fn.call(Fake.prototype);
}
} else {
try {
throw Error();
} catch (x) {
control = x;
} // TODO(luna): This will currently only throw if the function component
// tries to access React/ReactDOM/props. We should probably make this throw
// in simple components too
var maybePromise = fn(); // If the function component returns a promise, it's likely an async
// component, which we don't yet support. Attach a noop catch handler to
// silence the error.
// TODO: Implement component stacks for async client components?
if (maybePromise && typeof maybePromise.catch === "function") {
maybePromise.catch(function () {});
}
}
} catch (sample) {
// This is inlined manually because closure doesn't do it for us.
if (sample && control && typeof sample.stack === "string") {
return [sample.stack, control.stack];
}
}
return [null, null];
}
}; // $FlowFixMe[prop-missing]
RunInRootFrame.DetermineComponentFrameRoot.displayName =
"DetermineComponentFrameRoot";
var namePropDescriptor = Object.getOwnPropertyDescriptor(
RunInRootFrame.DetermineComponentFrameRoot,
"name"
); // Before ES6, the `name` property was not configurable.
if (namePropDescriptor && namePropDescriptor.configurable) {
// V8 utilizes a function's `name` property when generating a stack trace.
Object.defineProperty(
RunInRootFrame.DetermineComponentFrameRoot, // Configurable properties can be updated even if its writable descriptor
// is set to `false`.
// $FlowFixMe[cannot-write]
"name",
{
value: "DetermineComponentFrameRoot"
}
);
}
try {
var _RunInRootFrame$Deter =
RunInRootFrame.DetermineComponentFrameRoot(),
sampleStack = _RunInRootFrame$Deter[0],
controlStack = _RunInRootFrame$Deter[1];
if (sampleStack && controlStack) {
// This extracts the first frame from the sample that isn't also in the control.
// Skipping one frame that we assume is the frame that calls the two.
var sampleLines = sampleStack.split("\n");
var controlLines = controlStack.split("\n");
var s = 0;
var c = 0;
while (
s < sampleLines.length &&
!sampleLines[s].includes("DetermineComponentFrameRoot")
) {
s++;
}
while (
c < controlLines.length &&
!controlLines[c].includes("DetermineComponentFrameRoot")
) {
c++;
} // We couldn't find our intentionally injected common root frame, attempt
// to find another common root frame by search from the bottom of the
// control stack...
if (s === sampleLines.length || c === controlLines.length) {
s = sampleLines.length - 1;
c = controlLines.length - 1;
while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
// We expect at least one stack frame to be shared.
// Typically this will be the root most one. However, stack frames may be
// cut off due to maximum stack limits. In this case, one maybe cut off
// earlier than the other. We assume that the sample is longer or the same
// and there for cut off earlier. So we should find the root most frame in
// the sample somewhere in the control.
c--;
}
}
for (; s >= 1 && c >= 0; s--, c--) {
// Next we find the first one that isn't the same which should be the
// frame that called our sample function and the control.
if (sampleLines[s] !== controlLines[c]) {
// In V8, the first line is describing the message but other VMs don't.
// If we're about to return the first line, and the control is also on the same
// line, that's a pretty good indicator that our sample threw at same line as
// the control. I.e. before we entered the sample frame. So we ignore this result.
// This can happen if you passed a class to function component, or non-function.
if (s !== 1 || c !== 1) {
do {
s--;
c--; // We may still have similar intermediate frames from the construct call.
// The next one that isn't the same should be our match though.
if (c < 0 || sampleLines[s] !== controlLines[c]) {
// V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
var _frame =
"\n" + sampleLines[s].replace(" at new ", " at "); // If our component frame is labeled "<anonymous>"
// but we have a user-provided "displayName"
// splice it in to make the stack more readable.
if (fn.displayName && _frame.includes("<anonymous>")) {
_frame = _frame.replace("<anonymous>", fn.displayName);
}
if (true) {
if (typeof fn === "function") {
componentFrameCache.set(fn, _frame);
}
} // Return the line we found.
return _frame;
}
} while (s >= 1 && c >= 0);
}
break;
}
}
}
} finally {
reentry = false;
{
ReactCurrentDispatcher$2.current = previousDispatcher;
reenableLogs();
}
Error.prepareStackTrace = previousPrepareStackTrace;
} // Fallback to just using the name if we couldn't make it throw.
var name = fn ? fn.displayName || fn.name : "";
var syntheticFrame = name ? describeBuiltInComponentFrame(name) : "";
{
if (typeof fn === "function") {
componentFrameCache.set(fn, syntheticFrame);
}
}
return syntheticFrame;
}
function describeClassComponentFrame(ctor, ownerFn) {
{
return describeNativeComponentFrame(ctor, true);
}
}
function describeFunctionComponentFrame(fn, ownerFn) {
{
return describeNativeComponentFrame(fn, false);
}
}
function describeFiber(fiber) {
switch (fiber.tag) {
case HostHoistable:
case HostSingleton:
case HostComponent:
return describeBuiltInComponentFrame(fiber.type);
case LazyComponent:
return describeBuiltInComponentFrame("Lazy");
case SuspenseComponent:
return describeBuiltInComponentFrame("Suspense");
case SuspenseListComponent:
return describeBuiltInComponentFrame("SuspenseList");
case FunctionComponent:
case SimpleMemoComponent:
return describeFunctionComponentFrame(fiber.type);
case ForwardRef:
return describeFunctionComponentFrame(fiber.type.render);
case ClassComponent:
return describeClassComponentFrame(fiber.type);
default:
return "";
}
}
function getStackByFiberInDevAndProd(workInProgress) {
try {
var info = "";
var node = workInProgress;
do {
info += describeFiber(node);
if (true) {
// Add any Server Component stack frames in reverse order.
var debugInfo = node._debugInfo;
if (debugInfo) {
for (var i = debugInfo.length - 1; i >= 0; i--) {
var entry = debugInfo[i];
if (typeof entry.name === "string") {
info += describeDebugInfoFrame(entry.name, entry.env);
}
}
}
} // $FlowFixMe[incompatible-type] we bail out when we get a null
node = node.return;
} while (node);
return info;
} catch (x) {
return "\nError generating stack: " + x.message + "\n" + x.stack;
}
}
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
var current = null;
var isRendering = false;
@@ -14505,43 +14542,6 @@ if (__DEV__) {
return baseProps;
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
typeof reportError === "function" // In modern browsers, reportError will dispatch an error event,
? // emulating an uncaught JavaScript error.
reportError
@@ -15085,8 +15085,17 @@ if (__DEV__) {
}
} // This is a regular error, not a Suspense wakeable.
value = createCapturedValueAtFiber(value, sourceFiber);
renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start
var wrapperError = new Error(
"There was an error during concurrent rendering but React was able to recover by " +
"instead synchronously rendering the entire root.",
{
cause: value
}
);
queueConcurrentError(
createCapturedValueAtFiber(wrapperError, sourceFiber)
);
renderDidError(); // We didn't find a boundary that could handle this type of exception. Start
// over and traverse parent path again, this time treating the exception
// as an error.
@@ -15096,26 +15105,30 @@ if (__DEV__) {
return true;
}
var errorInfo = createCapturedValueAtFiber(value, sourceFiber);
var workInProgress = returnFiber;
do {
switch (workInProgress.tag) {
case HostRoot: {
var _errorInfo = value;
workInProgress.flags |= ShouldCapture;
var lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
var update = createRootErrorUpdate(
var _lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane);
var _update = createRootErrorUpdate(
workInProgress.stateNode,
_errorInfo,
lane
errorInfo,
_lane
);
enqueueCapturedUpdate(workInProgress, update);
enqueueCapturedUpdate(workInProgress, _update);
return false;
}
case ClassComponent:
var errorInfo = value;
// Capture and retry
var ctor = workInProgress.type;
var instance = workInProgress.stateNode;
@@ -15128,19 +15141,19 @@ if (__DEV__) {
) {
workInProgress.flags |= ShouldCapture;
var _lane = pickArbitraryLane(rootRenderLanes);
var _lane2 = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane2); // Schedule the error boundary to re-render using updated state
var _update = createClassErrorUpdate(_lane);
var _update2 = createClassErrorUpdate(_lane2);
initializeClassErrorUpdate(
_update,
_update2,
root,
workInProgress,
errorInfo
);
enqueueCapturedUpdate(workInProgress, _update);
enqueueCapturedUpdate(workInProgress, _update2);
return false;
}
@@ -17388,20 +17401,12 @@ if (__DEV__) {
function retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
recoverableError
renderLanes
) {
// Falling back to client rendering. Because this has performance
// implications, it's considered a recoverable error, even though the user
// likely won't observe anything wrong with the UI.
//
// The error is passed in as an argument to enforce that every caller provide
// a custom message, or explicitly opt out (currently the only path that opts
// out is legacy mode; every concurrent path provides an error).
if (recoverableError !== null) {
queueHydrationError(recoverableError);
} // This will add the old fiber to the deletion list
// This will add the old fiber to the deletion list
reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
var nextProps = workInProgress.pendingProps;
@@ -17487,9 +17492,7 @@ if (__DEV__) {
message = _getSuspenseInstanceF.message;
stack = _getSuspenseInstanceF.stack;
componentStack = _getSuspenseInstanceF.componentStack;
}
var capturedValue = null; // TODO: Figure out a better signal than encoding a magic digest value.
} // TODO: Figure out a better signal than encoding a magic digest value.
{
var error;
@@ -17507,17 +17510,17 @@ if (__DEV__) {
error.stack = stack || "";
error.digest = digest;
capturedValue = createCapturedValueFromError(
var capturedValue = createCapturedValueFromError(
error,
componentStack === undefined ? null : componentStack
);
queueHydrationError(capturedValue);
}
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
capturedValue
renderLanes
);
}
@@ -17592,8 +17595,7 @@ if (__DEV__) {
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
null
renderLanes
);
} else if (isSuspenseInstancePending()) {
// This component is still pending more data from the server, so we can't hydrate its
@@ -17632,22 +17634,13 @@ if (__DEV__) {
// something either suspended or errored.
if (workInProgress.flags & ForceClientRender) {
// Something errored during hydration. Try again without hydrating.
// The error should've already been logged in throwException.
pushPrimaryTreeSuspenseHandler(workInProgress);
workInProgress.flags &= ~ForceClientRender;
var _capturedValue = createCapturedValueFromError(
new Error(
"There was an error while hydrating this Suspense boundary. " +
"Switched to client rendering."
),
null
);
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
_capturedValue
renderLanes
);
} else if (workInProgress.memoizedState !== null) {
// Something suspended and we should still be in dehydrated mode.
@@ -27164,11 +27157,12 @@ if (__DEV__) {
);
}
}
function renderDidError(error) {
function renderDidError() {
if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
workInProgressRootExitStatus = RootErrored;
}
}
function queueConcurrentError(error) {
if (workInProgressRootConcurrentErrors === null) {
workInProgressRootConcurrentErrors = [error];
} else {
+429 -435
View File
@@ -66,7 +66,7 @@ if (__DEV__) {
return self;
}
var ReactVersion = "19.0.0-www-modern-8336910b";
var ReactVersion = "19.0.0-www-modern-792ee5bd";
var LegacyRoot = 0;
var ConcurrentRoot = 1;
@@ -3351,6 +3351,394 @@ if (__DEV__) {
}
}
var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher;
var prefix;
function describeBuiltInComponentFrame(name, ownerFn) {
{
if (prefix === undefined) {
// Extract the VM specific prefix used by each line.
try {
throw Error();
} catch (x) {
var match = x.stack.trim().match(/\n( *(at )?)/);
prefix = (match && match[1]) || "";
}
} // We use the prefix to ensure our stacks line up with native stack frames.
return "\n" + prefix + name;
}
}
function describeDebugInfoFrame(name, env) {
return describeBuiltInComponentFrame(
name + (env ? " (" + env + ")" : "")
);
}
var reentry = false;
var componentFrameCache;
{
var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map;
componentFrameCache = new PossiblyWeakMap$1();
}
/**
* Leverages native browser/VM stack frames to get proper details (e.g.
* filename, line + col number) for a single component in a component stack. We
* do this by:
* (1) throwing and catching an error in the function - this will be our
* control error.
* (2) calling the component which will eventually throw an error that we'll
* catch - this will be our sample error.
* (3) diffing the control and sample error stacks to find the stack frame
* which represents our component.
*/
function describeNativeComponentFrame(fn, construct) {
// If something asked for a stack inside a fake render, it should get ignored.
if (!fn || reentry) {
return "";
}
{
var frame = componentFrameCache.get(fn);
if (frame !== undefined) {
return frame;
}
}
reentry = true;
var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe[incompatible-type] It does accept undefined.
Error.prepareStackTrace = undefined;
var previousDispatcher;
{
previousDispatcher = ReactCurrentDispatcher$2.current; // Set the dispatcher in DEV because this might be call in the render function
// for warnings.
ReactCurrentDispatcher$2.current = null;
disableLogs();
}
/**
* Finding a common stack frame between sample and control errors can be
* tricky given the different types and levels of stack trace truncation from
* different JS VMs. So instead we'll attempt to control what that common
* frame should be through this object method:
* Having both the sample and control errors be in the function under the
* `DescribeNativeComponentFrameRoot` property, + setting the `name` and
* `displayName` properties of the function ensures that a stack
* frame exists that has the method name `DescribeNativeComponentFrameRoot` in
* it for both control and sample stacks.
*/
var RunInRootFrame = {
DetermineComponentFrameRoot: function () {
var control;
try {
// This should throw.
if (construct) {
// Something should be setting the props in the constructor.
var Fake = function () {
throw Error();
}; // $FlowFixMe[prop-missing]
Object.defineProperty(Fake.prototype, "props", {
set: function () {
// We use a throwing setter instead of frozen or non-writable props
// because that won't throw in a non-strict mode function.
throw Error();
}
});
if (typeof Reflect === "object" && Reflect.construct) {
// We construct a different control for this case to include any extra
// frames added by the construct call.
try {
Reflect.construct(Fake, []);
} catch (x) {
control = x;
}
Reflect.construct(fn, [], Fake);
} else {
try {
Fake.call();
} catch (x) {
control = x;
} // $FlowFixMe[prop-missing] found when upgrading Flow
fn.call(Fake.prototype);
}
} else {
try {
throw Error();
} catch (x) {
control = x;
} // TODO(luna): This will currently only throw if the function component
// tries to access React/ReactDOM/props. We should probably make this throw
// in simple components too
var maybePromise = fn(); // If the function component returns a promise, it's likely an async
// component, which we don't yet support. Attach a noop catch handler to
// silence the error.
// TODO: Implement component stacks for async client components?
if (maybePromise && typeof maybePromise.catch === "function") {
maybePromise.catch(function () {});
}
}
} catch (sample) {
// This is inlined manually because closure doesn't do it for us.
if (sample && control && typeof sample.stack === "string") {
return [sample.stack, control.stack];
}
}
return [null, null];
}
}; // $FlowFixMe[prop-missing]
RunInRootFrame.DetermineComponentFrameRoot.displayName =
"DetermineComponentFrameRoot";
var namePropDescriptor = Object.getOwnPropertyDescriptor(
RunInRootFrame.DetermineComponentFrameRoot,
"name"
); // Before ES6, the `name` property was not configurable.
if (namePropDescriptor && namePropDescriptor.configurable) {
// V8 utilizes a function's `name` property when generating a stack trace.
Object.defineProperty(
RunInRootFrame.DetermineComponentFrameRoot, // Configurable properties can be updated even if its writable descriptor
// is set to `false`.
// $FlowFixMe[cannot-write]
"name",
{
value: "DetermineComponentFrameRoot"
}
);
}
try {
var _RunInRootFrame$Deter =
RunInRootFrame.DetermineComponentFrameRoot(),
sampleStack = _RunInRootFrame$Deter[0],
controlStack = _RunInRootFrame$Deter[1];
if (sampleStack && controlStack) {
// This extracts the first frame from the sample that isn't also in the control.
// Skipping one frame that we assume is the frame that calls the two.
var sampleLines = sampleStack.split("\n");
var controlLines = controlStack.split("\n");
var s = 0;
var c = 0;
while (
s < sampleLines.length &&
!sampleLines[s].includes("DetermineComponentFrameRoot")
) {
s++;
}
while (
c < controlLines.length &&
!controlLines[c].includes("DetermineComponentFrameRoot")
) {
c++;
} // We couldn't find our intentionally injected common root frame, attempt
// to find another common root frame by search from the bottom of the
// control stack...
if (s === sampleLines.length || c === controlLines.length) {
s = sampleLines.length - 1;
c = controlLines.length - 1;
while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
// We expect at least one stack frame to be shared.
// Typically this will be the root most one. However, stack frames may be
// cut off due to maximum stack limits. In this case, one maybe cut off
// earlier than the other. We assume that the sample is longer or the same
// and there for cut off earlier. So we should find the root most frame in
// the sample somewhere in the control.
c--;
}
}
for (; s >= 1 && c >= 0; s--, c--) {
// Next we find the first one that isn't the same which should be the
// frame that called our sample function and the control.
if (sampleLines[s] !== controlLines[c]) {
// In V8, the first line is describing the message but other VMs don't.
// If we're about to return the first line, and the control is also on the same
// line, that's a pretty good indicator that our sample threw at same line as
// the control. I.e. before we entered the sample frame. So we ignore this result.
// This can happen if you passed a class to function component, or non-function.
if (s !== 1 || c !== 1) {
do {
s--;
c--; // We may still have similar intermediate frames from the construct call.
// The next one that isn't the same should be our match though.
if (c < 0 || sampleLines[s] !== controlLines[c]) {
// V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
var _frame =
"\n" + sampleLines[s].replace(" at new ", " at "); // If our component frame is labeled "<anonymous>"
// but we have a user-provided "displayName"
// splice it in to make the stack more readable.
if (fn.displayName && _frame.includes("<anonymous>")) {
_frame = _frame.replace("<anonymous>", fn.displayName);
}
if (true) {
if (typeof fn === "function") {
componentFrameCache.set(fn, _frame);
}
} // Return the line we found.
return _frame;
}
} while (s >= 1 && c >= 0);
}
break;
}
}
}
} finally {
reentry = false;
{
ReactCurrentDispatcher$2.current = previousDispatcher;
reenableLogs();
}
Error.prepareStackTrace = previousPrepareStackTrace;
} // Fallback to just using the name if we couldn't make it throw.
var name = fn ? fn.displayName || fn.name : "";
var syntheticFrame = name ? describeBuiltInComponentFrame(name) : "";
{
if (typeof fn === "function") {
componentFrameCache.set(fn, syntheticFrame);
}
}
return syntheticFrame;
}
function describeClassComponentFrame(ctor, ownerFn) {
{
return describeNativeComponentFrame(ctor, true);
}
}
function describeFunctionComponentFrame(fn, ownerFn) {
{
return describeNativeComponentFrame(fn, false);
}
}
function describeFiber(fiber) {
switch (fiber.tag) {
case HostHoistable:
case HostSingleton:
case HostComponent:
return describeBuiltInComponentFrame(fiber.type);
case LazyComponent:
return describeBuiltInComponentFrame("Lazy");
case SuspenseComponent:
return describeBuiltInComponentFrame("Suspense");
case SuspenseListComponent:
return describeBuiltInComponentFrame("SuspenseList");
case FunctionComponent:
case SimpleMemoComponent:
return describeFunctionComponentFrame(fiber.type);
case ForwardRef:
return describeFunctionComponentFrame(fiber.type.render);
case ClassComponent:
return describeClassComponentFrame(fiber.type);
default:
return "";
}
}
function getStackByFiberInDevAndProd(workInProgress) {
try {
var info = "";
var node = workInProgress;
do {
info += describeFiber(node);
if (true) {
// Add any Server Component stack frames in reverse order.
var debugInfo = node._debugInfo;
if (debugInfo) {
for (var i = debugInfo.length - 1; i >= 0; i--) {
var entry = debugInfo[i];
if (typeof entry.name === "string") {
info += describeDebugInfoFrame(entry.name, entry.env);
}
}
}
} // $FlowFixMe[incompatible-type] we bail out when we get a null
node = node.return;
} while (node);
return info;
} catch (x) {
return "\nError generating stack: " + x.message + "\n" + x.stack;
}
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
var contextStackCursor = createCursor(null);
var contextFiberStackCursor = createCursor(null);
var rootInstanceStackCursor = createCursor(null); // Represents the nearest host transition provider (in React DOM, a <form />)
@@ -5567,357 +5955,6 @@ if (__DEV__) {
return true;
}
var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher;
var prefix;
function describeBuiltInComponentFrame(name, ownerFn) {
{
if (prefix === undefined) {
// Extract the VM specific prefix used by each line.
try {
throw Error();
} catch (x) {
var match = x.stack.trim().match(/\n( *(at )?)/);
prefix = (match && match[1]) || "";
}
} // We use the prefix to ensure our stacks line up with native stack frames.
return "\n" + prefix + name;
}
}
function describeDebugInfoFrame(name, env) {
return describeBuiltInComponentFrame(
name + (env ? " (" + env + ")" : "")
);
}
var reentry = false;
var componentFrameCache;
{
var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map;
componentFrameCache = new PossiblyWeakMap$1();
}
/**
* Leverages native browser/VM stack frames to get proper details (e.g.
* filename, line + col number) for a single component in a component stack. We
* do this by:
* (1) throwing and catching an error in the function - this will be our
* control error.
* (2) calling the component which will eventually throw an error that we'll
* catch - this will be our sample error.
* (3) diffing the control and sample error stacks to find the stack frame
* which represents our component.
*/
function describeNativeComponentFrame(fn, construct) {
// If something asked for a stack inside a fake render, it should get ignored.
if (!fn || reentry) {
return "";
}
{
var frame = componentFrameCache.get(fn);
if (frame !== undefined) {
return frame;
}
}
reentry = true;
var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe[incompatible-type] It does accept undefined.
Error.prepareStackTrace = undefined;
var previousDispatcher;
{
previousDispatcher = ReactCurrentDispatcher$2.current; // Set the dispatcher in DEV because this might be call in the render function
// for warnings.
ReactCurrentDispatcher$2.current = null;
disableLogs();
}
/**
* Finding a common stack frame between sample and control errors can be
* tricky given the different types and levels of stack trace truncation from
* different JS VMs. So instead we'll attempt to control what that common
* frame should be through this object method:
* Having both the sample and control errors be in the function under the
* `DescribeNativeComponentFrameRoot` property, + setting the `name` and
* `displayName` properties of the function ensures that a stack
* frame exists that has the method name `DescribeNativeComponentFrameRoot` in
* it for both control and sample stacks.
*/
var RunInRootFrame = {
DetermineComponentFrameRoot: function () {
var control;
try {
// This should throw.
if (construct) {
// Something should be setting the props in the constructor.
var Fake = function () {
throw Error();
}; // $FlowFixMe[prop-missing]
Object.defineProperty(Fake.prototype, "props", {
set: function () {
// We use a throwing setter instead of frozen or non-writable props
// because that won't throw in a non-strict mode function.
throw Error();
}
});
if (typeof Reflect === "object" && Reflect.construct) {
// We construct a different control for this case to include any extra
// frames added by the construct call.
try {
Reflect.construct(Fake, []);
} catch (x) {
control = x;
}
Reflect.construct(fn, [], Fake);
} else {
try {
Fake.call();
} catch (x) {
control = x;
} // $FlowFixMe[prop-missing] found when upgrading Flow
fn.call(Fake.prototype);
}
} else {
try {
throw Error();
} catch (x) {
control = x;
} // TODO(luna): This will currently only throw if the function component
// tries to access React/ReactDOM/props. We should probably make this throw
// in simple components too
var maybePromise = fn(); // If the function component returns a promise, it's likely an async
// component, which we don't yet support. Attach a noop catch handler to
// silence the error.
// TODO: Implement component stacks for async client components?
if (maybePromise && typeof maybePromise.catch === "function") {
maybePromise.catch(function () {});
}
}
} catch (sample) {
// This is inlined manually because closure doesn't do it for us.
if (sample && control && typeof sample.stack === "string") {
return [sample.stack, control.stack];
}
}
return [null, null];
}
}; // $FlowFixMe[prop-missing]
RunInRootFrame.DetermineComponentFrameRoot.displayName =
"DetermineComponentFrameRoot";
var namePropDescriptor = Object.getOwnPropertyDescriptor(
RunInRootFrame.DetermineComponentFrameRoot,
"name"
); // Before ES6, the `name` property was not configurable.
if (namePropDescriptor && namePropDescriptor.configurable) {
// V8 utilizes a function's `name` property when generating a stack trace.
Object.defineProperty(
RunInRootFrame.DetermineComponentFrameRoot, // Configurable properties can be updated even if its writable descriptor
// is set to `false`.
// $FlowFixMe[cannot-write]
"name",
{
value: "DetermineComponentFrameRoot"
}
);
}
try {
var _RunInRootFrame$Deter =
RunInRootFrame.DetermineComponentFrameRoot(),
sampleStack = _RunInRootFrame$Deter[0],
controlStack = _RunInRootFrame$Deter[1];
if (sampleStack && controlStack) {
// This extracts the first frame from the sample that isn't also in the control.
// Skipping one frame that we assume is the frame that calls the two.
var sampleLines = sampleStack.split("\n");
var controlLines = controlStack.split("\n");
var s = 0;
var c = 0;
while (
s < sampleLines.length &&
!sampleLines[s].includes("DetermineComponentFrameRoot")
) {
s++;
}
while (
c < controlLines.length &&
!controlLines[c].includes("DetermineComponentFrameRoot")
) {
c++;
} // We couldn't find our intentionally injected common root frame, attempt
// to find another common root frame by search from the bottom of the
// control stack...
if (s === sampleLines.length || c === controlLines.length) {
s = sampleLines.length - 1;
c = controlLines.length - 1;
while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
// We expect at least one stack frame to be shared.
// Typically this will be the root most one. However, stack frames may be
// cut off due to maximum stack limits. In this case, one maybe cut off
// earlier than the other. We assume that the sample is longer or the same
// and there for cut off earlier. So we should find the root most frame in
// the sample somewhere in the control.
c--;
}
}
for (; s >= 1 && c >= 0; s--, c--) {
// Next we find the first one that isn't the same which should be the
// frame that called our sample function and the control.
if (sampleLines[s] !== controlLines[c]) {
// In V8, the first line is describing the message but other VMs don't.
// If we're about to return the first line, and the control is also on the same
// line, that's a pretty good indicator that our sample threw at same line as
// the control. I.e. before we entered the sample frame. So we ignore this result.
// This can happen if you passed a class to function component, or non-function.
if (s !== 1 || c !== 1) {
do {
s--;
c--; // We may still have similar intermediate frames from the construct call.
// The next one that isn't the same should be our match though.
if (c < 0 || sampleLines[s] !== controlLines[c]) {
// V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
var _frame =
"\n" + sampleLines[s].replace(" at new ", " at "); // If our component frame is labeled "<anonymous>"
// but we have a user-provided "displayName"
// splice it in to make the stack more readable.
if (fn.displayName && _frame.includes("<anonymous>")) {
_frame = _frame.replace("<anonymous>", fn.displayName);
}
if (true) {
if (typeof fn === "function") {
componentFrameCache.set(fn, _frame);
}
} // Return the line we found.
return _frame;
}
} while (s >= 1 && c >= 0);
}
break;
}
}
}
} finally {
reentry = false;
{
ReactCurrentDispatcher$2.current = previousDispatcher;
reenableLogs();
}
Error.prepareStackTrace = previousPrepareStackTrace;
} // Fallback to just using the name if we couldn't make it throw.
var name = fn ? fn.displayName || fn.name : "";
var syntheticFrame = name ? describeBuiltInComponentFrame(name) : "";
{
if (typeof fn === "function") {
componentFrameCache.set(fn, syntheticFrame);
}
}
return syntheticFrame;
}
function describeClassComponentFrame(ctor, ownerFn) {
{
return describeNativeComponentFrame(ctor, true);
}
}
function describeFunctionComponentFrame(fn, ownerFn) {
{
return describeNativeComponentFrame(fn, false);
}
}
function describeFiber(fiber) {
switch (fiber.tag) {
case HostHoistable:
case HostSingleton:
case HostComponent:
return describeBuiltInComponentFrame(fiber.type);
case LazyComponent:
return describeBuiltInComponentFrame("Lazy");
case SuspenseComponent:
return describeBuiltInComponentFrame("Suspense");
case SuspenseListComponent:
return describeBuiltInComponentFrame("SuspenseList");
case FunctionComponent:
case SimpleMemoComponent:
return describeFunctionComponentFrame(fiber.type);
case ForwardRef:
return describeFunctionComponentFrame(fiber.type.render);
case ClassComponent:
return describeClassComponentFrame(fiber.type);
default:
return "";
}
}
function getStackByFiberInDevAndProd(workInProgress) {
try {
var info = "";
var node = workInProgress;
do {
info += describeFiber(node);
if (true) {
// Add any Server Component stack frames in reverse order.
var debugInfo = node._debugInfo;
if (debugInfo) {
for (var i = debugInfo.length - 1; i >= 0; i--) {
var entry = debugInfo[i];
if (typeof entry.name === "string") {
info += describeDebugInfoFrame(entry.name, entry.env);
}
}
}
} // $FlowFixMe[incompatible-type] we bail out when we get a null
node = node.return;
} while (node);
return info;
} catch (x) {
return "\nError generating stack: " + x.message + "\n" + x.stack;
}
}
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
var current = null;
var isRendering = false;
@@ -14215,43 +14252,6 @@ if (__DEV__) {
return baseProps;
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
typeof reportError === "function" // In modern browsers, reportError will dispatch an error event,
? // emulating an uncaught JavaScript error.
reportError
@@ -14699,8 +14699,17 @@ if (__DEV__) {
}
} // This is a regular error, not a Suspense wakeable.
value = createCapturedValueAtFiber(value, sourceFiber);
renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start
var wrapperError = new Error(
"There was an error during concurrent rendering but React was able to recover by " +
"instead synchronously rendering the entire root.",
{
cause: value
}
);
queueConcurrentError(
createCapturedValueAtFiber(wrapperError, sourceFiber)
);
renderDidError(); // We didn't find a boundary that could handle this type of exception. Start
// over and traverse parent path again, this time treating the exception
// as an error.
@@ -14710,26 +14719,30 @@ if (__DEV__) {
return true;
}
var errorInfo = createCapturedValueAtFiber(value, sourceFiber);
var workInProgress = returnFiber;
do {
switch (workInProgress.tag) {
case HostRoot: {
var _errorInfo = value;
workInProgress.flags |= ShouldCapture;
var lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
var update = createRootErrorUpdate(
var _lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane);
var _update = createRootErrorUpdate(
workInProgress.stateNode,
_errorInfo,
lane
errorInfo,
_lane
);
enqueueCapturedUpdate(workInProgress, update);
enqueueCapturedUpdate(workInProgress, _update);
return false;
}
case ClassComponent:
var errorInfo = value;
// Capture and retry
var ctor = workInProgress.type;
var instance = workInProgress.stateNode;
@@ -14742,19 +14755,19 @@ if (__DEV__) {
) {
workInProgress.flags |= ShouldCapture;
var _lane = pickArbitraryLane(rootRenderLanes);
var _lane2 = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane2); // Schedule the error boundary to re-render using updated state
var _update = createClassErrorUpdate(_lane);
var _update2 = createClassErrorUpdate(_lane2);
initializeClassErrorUpdate(
_update,
_update2,
root,
workInProgress,
errorInfo
);
enqueueCapturedUpdate(workInProgress, _update);
enqueueCapturedUpdate(workInProgress, _update2);
return false;
}
@@ -16839,20 +16852,12 @@ if (__DEV__) {
function retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
recoverableError
renderLanes
) {
// Falling back to client rendering. Because this has performance
// implications, it's considered a recoverable error, even though the user
// likely won't observe anything wrong with the UI.
//
// The error is passed in as an argument to enforce that every caller provide
// a custom message, or explicitly opt out (currently the only path that opts
// out is legacy mode; every concurrent path provides an error).
if (recoverableError !== null) {
queueHydrationError(recoverableError);
} // This will add the old fiber to the deletion list
// This will add the old fiber to the deletion list
reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
var nextProps = workInProgress.pendingProps;
@@ -16938,9 +16943,7 @@ if (__DEV__) {
message = _getSuspenseInstanceF.message;
stack = _getSuspenseInstanceF.stack;
componentStack = _getSuspenseInstanceF.componentStack;
}
var capturedValue = null; // TODO: Figure out a better signal than encoding a magic digest value.
} // TODO: Figure out a better signal than encoding a magic digest value.
{
var error;
@@ -16958,17 +16961,17 @@ if (__DEV__) {
error.stack = stack || "";
error.digest = digest;
capturedValue = createCapturedValueFromError(
var capturedValue = createCapturedValueFromError(
error,
componentStack === undefined ? null : componentStack
);
queueHydrationError(capturedValue);
}
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
capturedValue
renderLanes
);
}
@@ -17043,8 +17046,7 @@ if (__DEV__) {
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
null
renderLanes
);
} else if (isSuspenseInstancePending()) {
// This component is still pending more data from the server, so we can't hydrate its
@@ -17083,22 +17085,13 @@ if (__DEV__) {
// something either suspended or errored.
if (workInProgress.flags & ForceClientRender) {
// Something errored during hydration. Try again without hydrating.
// The error should've already been logged in throwException.
pushPrimaryTreeSuspenseHandler(workInProgress);
workInProgress.flags &= ~ForceClientRender;
var _capturedValue = createCapturedValueFromError(
new Error(
"There was an error while hydrating this Suspense boundary. " +
"Switched to client rendering."
),
null
);
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
_capturedValue
renderLanes
);
} else if (workInProgress.memoizedState !== null) {
// Something suspended and we should still be in dehydrated mode.
@@ -26371,11 +26364,12 @@ if (__DEV__) {
);
}
}
function renderDidError(error) {
function renderDidError() {
if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
workInProgressRootExitStatus = RootErrored;
}
}
function queueConcurrentError(error) {
if (workInProgressRootConcurrentErrors === null) {
workInProgressRootConcurrentErrors = [error];
} else {
File diff suppressed because it is too large Load Diff
+326 -338
View File
@@ -719,7 +719,197 @@ function is(x, y) {
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
}
var objectIs = "function" === typeof Object.is ? Object.is : is,
contextStackCursor = createCursor(null),
prefix;
function describeBuiltInComponentFrame(name) {
if (void 0 === prefix)
try {
throw Error();
} catch (x) {
var match = x.stack.trim().match(/\n( *(at )?)/);
prefix = (match && match[1]) || "";
}
return "\n" + prefix + name;
}
var reentry = !1;
function describeNativeComponentFrame(fn, construct) {
if (!fn || reentry) return "";
reentry = !0;
var previousPrepareStackTrace = Error.prepareStackTrace;
Error.prepareStackTrace = void 0;
var RunInRootFrame = {
DetermineComponentFrameRoot: function () {
try {
if (construct) {
var Fake = function () {
throw Error();
};
Object.defineProperty(Fake.prototype, "props", {
set: function () {
throw Error();
}
});
if ("object" === typeof Reflect && Reflect.construct) {
try {
Reflect.construct(Fake, []);
} catch (x) {
var control = x;
}
Reflect.construct(fn, [], Fake);
} else {
try {
Fake.call();
} catch (x$10) {
control = x$10;
}
fn.call(Fake.prototype);
}
} else {
try {
throw Error();
} catch (x$11) {
control = x$11;
}
(Fake = fn()) &&
"function" === typeof Fake.catch &&
Fake.catch(function () {});
}
} catch (sample) {
if (sample && control && "string" === typeof sample.stack)
return [sample.stack, control.stack];
}
return [null, null];
}
};
RunInRootFrame.DetermineComponentFrameRoot.displayName =
"DetermineComponentFrameRoot";
var namePropDescriptor = Object.getOwnPropertyDescriptor(
RunInRootFrame.DetermineComponentFrameRoot,
"name"
);
namePropDescriptor &&
namePropDescriptor.configurable &&
Object.defineProperty(RunInRootFrame.DetermineComponentFrameRoot, "name", {
value: "DetermineComponentFrameRoot"
});
try {
var _RunInRootFrame$Deter = RunInRootFrame.DetermineComponentFrameRoot(),
sampleStack = _RunInRootFrame$Deter[0],
controlStack = _RunInRootFrame$Deter[1];
if (sampleStack && controlStack) {
var sampleLines = sampleStack.split("\n"),
controlLines = controlStack.split("\n");
for (
namePropDescriptor = RunInRootFrame = 0;
RunInRootFrame < sampleLines.length &&
!sampleLines[RunInRootFrame].includes("DetermineComponentFrameRoot");
)
RunInRootFrame++;
for (
;
namePropDescriptor < controlLines.length &&
!controlLines[namePropDescriptor].includes(
"DetermineComponentFrameRoot"
);
)
namePropDescriptor++;
if (
RunInRootFrame === sampleLines.length ||
namePropDescriptor === controlLines.length
)
for (
RunInRootFrame = sampleLines.length - 1,
namePropDescriptor = controlLines.length - 1;
1 <= RunInRootFrame &&
0 <= namePropDescriptor &&
sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor];
)
namePropDescriptor--;
for (
;
1 <= RunInRootFrame && 0 <= namePropDescriptor;
RunInRootFrame--, namePropDescriptor--
)
if (sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor]) {
if (1 !== RunInRootFrame || 1 !== namePropDescriptor) {
do
if (
(RunInRootFrame--,
namePropDescriptor--,
0 > namePropDescriptor ||
sampleLines[RunInRootFrame] !==
controlLines[namePropDescriptor])
) {
var frame =
"\n" +
sampleLines[RunInRootFrame].replace(" at new ", " at ");
fn.displayName &&
frame.includes("<anonymous>") &&
(frame = frame.replace("<anonymous>", fn.displayName));
return frame;
}
while (1 <= RunInRootFrame && 0 <= namePropDescriptor);
}
break;
}
}
} finally {
(reentry = !1), (Error.prepareStackTrace = previousPrepareStackTrace);
}
return (previousPrepareStackTrace = fn ? fn.displayName || fn.name : "")
? describeBuiltInComponentFrame(previousPrepareStackTrace)
: "";
}
function describeFiber(fiber) {
switch (fiber.tag) {
case 26:
case 27:
case 5:
return describeBuiltInComponentFrame(fiber.type);
case 16:
return describeBuiltInComponentFrame("Lazy");
case 13:
return describeBuiltInComponentFrame("Suspense");
case 19:
return describeBuiltInComponentFrame("SuspenseList");
case 0:
case 15:
return (fiber = describeNativeComponentFrame(fiber.type, !1)), fiber;
case 11:
return (
(fiber = describeNativeComponentFrame(fiber.type.render, !1)), fiber
);
case 1:
return (fiber = describeNativeComponentFrame(fiber.type, !0)), fiber;
default:
return "";
}
}
function getStackByFiberInDevAndProd(workInProgress) {
try {
var info = "";
do
(info += describeFiber(workInProgress)),
(workInProgress = workInProgress.return);
while (workInProgress);
return info;
} catch (x) {
return "\nError generating stack: " + x.message + "\n" + x.stack;
}
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
if ("object" === typeof value && null !== value) {
var stack = CapturedStacks.get(value);
"string" !== typeof stack &&
((stack = getStackByFiberInDevAndProd(source)),
CapturedStacks.set(value, stack));
} else stack = getStackByFiberInDevAndProd(source);
return { value: value, source: source, stack: stack };
}
var contextStackCursor = createCursor(null),
contextFiberStackCursor = createCursor(null),
rootInstanceStackCursor = createCursor(null),
hostTransitionProviderCursor = createCursor(null),
@@ -756,8 +946,9 @@ function popHostContext(fiber) {
(pop(hostTransitionProviderCursor),
(HostTransitionContext._currentValue2 = null));
}
var hydrationErrors = null,
concurrentQueues = [],
var hydrationErrors = null;
Error(formatProdErrorMessage(519));
var concurrentQueues = [],
concurrentQueuesIndex = 0,
concurrentlyUpdatedLanes = 0;
function finishQueueingConcurrentUpdates() {
@@ -860,14 +1051,14 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) {
var didPerformSomeWork = !1;
for (var root = firstScheduledRoot; null !== root; ) {
if (!onlyLegacy) {
var workInProgressRootRenderLanes$11 = workInProgressRootRenderLanes;
workInProgressRootRenderLanes$11 = getNextLanes(
var workInProgressRootRenderLanes$13 = workInProgressRootRenderLanes;
workInProgressRootRenderLanes$13 = getNextLanes(
root,
root === workInProgressRoot ? workInProgressRootRenderLanes$11 : 0
root === workInProgressRoot ? workInProgressRootRenderLanes$13 : 0
);
0 !== (workInProgressRootRenderLanes$11 & 3) &&
0 !== (workInProgressRootRenderLanes$13 & 3) &&
((didPerformSomeWork = !0),
performSyncWorkOnRoot(root, workInProgressRootRenderLanes$11));
performSyncWorkOnRoot(root, workInProgressRootRenderLanes$13));
}
root = root.next;
}
@@ -1301,186 +1492,6 @@ function shallowEqual(objA, objB) {
}
return !0;
}
var prefix;
function describeBuiltInComponentFrame(name) {
if (void 0 === prefix)
try {
throw Error();
} catch (x) {
var match = x.stack.trim().match(/\n( *(at )?)/);
prefix = (match && match[1]) || "";
}
return "\n" + prefix + name;
}
var reentry = !1;
function describeNativeComponentFrame(fn, construct) {
if (!fn || reentry) return "";
reentry = !0;
var previousPrepareStackTrace = Error.prepareStackTrace;
Error.prepareStackTrace = void 0;
var RunInRootFrame = {
DetermineComponentFrameRoot: function () {
try {
if (construct) {
var Fake = function () {
throw Error();
};
Object.defineProperty(Fake.prototype, "props", {
set: function () {
throw Error();
}
});
if ("object" === typeof Reflect && Reflect.construct) {
try {
Reflect.construct(Fake, []);
} catch (x) {
var control = x;
}
Reflect.construct(fn, [], Fake);
} else {
try {
Fake.call();
} catch (x$16) {
control = x$16;
}
fn.call(Fake.prototype);
}
} else {
try {
throw Error();
} catch (x$17) {
control = x$17;
}
(Fake = fn()) &&
"function" === typeof Fake.catch &&
Fake.catch(function () {});
}
} catch (sample) {
if (sample && control && "string" === typeof sample.stack)
return [sample.stack, control.stack];
}
return [null, null];
}
};
RunInRootFrame.DetermineComponentFrameRoot.displayName =
"DetermineComponentFrameRoot";
var namePropDescriptor = Object.getOwnPropertyDescriptor(
RunInRootFrame.DetermineComponentFrameRoot,
"name"
);
namePropDescriptor &&
namePropDescriptor.configurable &&
Object.defineProperty(RunInRootFrame.DetermineComponentFrameRoot, "name", {
value: "DetermineComponentFrameRoot"
});
try {
var _RunInRootFrame$Deter = RunInRootFrame.DetermineComponentFrameRoot(),
sampleStack = _RunInRootFrame$Deter[0],
controlStack = _RunInRootFrame$Deter[1];
if (sampleStack && controlStack) {
var sampleLines = sampleStack.split("\n"),
controlLines = controlStack.split("\n");
for (
namePropDescriptor = RunInRootFrame = 0;
RunInRootFrame < sampleLines.length &&
!sampleLines[RunInRootFrame].includes("DetermineComponentFrameRoot");
)
RunInRootFrame++;
for (
;
namePropDescriptor < controlLines.length &&
!controlLines[namePropDescriptor].includes(
"DetermineComponentFrameRoot"
);
)
namePropDescriptor++;
if (
RunInRootFrame === sampleLines.length ||
namePropDescriptor === controlLines.length
)
for (
RunInRootFrame = sampleLines.length - 1,
namePropDescriptor = controlLines.length - 1;
1 <= RunInRootFrame &&
0 <= namePropDescriptor &&
sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor];
)
namePropDescriptor--;
for (
;
1 <= RunInRootFrame && 0 <= namePropDescriptor;
RunInRootFrame--, namePropDescriptor--
)
if (sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor]) {
if (1 !== RunInRootFrame || 1 !== namePropDescriptor) {
do
if (
(RunInRootFrame--,
namePropDescriptor--,
0 > namePropDescriptor ||
sampleLines[RunInRootFrame] !==
controlLines[namePropDescriptor])
) {
var frame =
"\n" +
sampleLines[RunInRootFrame].replace(" at new ", " at ");
fn.displayName &&
frame.includes("<anonymous>") &&
(frame = frame.replace("<anonymous>", fn.displayName));
return frame;
}
while (1 <= RunInRootFrame && 0 <= namePropDescriptor);
}
break;
}
}
} finally {
(reentry = !1), (Error.prepareStackTrace = previousPrepareStackTrace);
}
return (previousPrepareStackTrace = fn ? fn.displayName || fn.name : "")
? describeBuiltInComponentFrame(previousPrepareStackTrace)
: "";
}
function describeFiber(fiber) {
switch (fiber.tag) {
case 26:
case 27:
case 5:
return describeBuiltInComponentFrame(fiber.type);
case 16:
return describeBuiltInComponentFrame("Lazy");
case 13:
return describeBuiltInComponentFrame("Suspense");
case 19:
return describeBuiltInComponentFrame("SuspenseList");
case 0:
case 15:
return (fiber = describeNativeComponentFrame(fiber.type, !1)), fiber;
case 11:
return (
(fiber = describeNativeComponentFrame(fiber.type.render, !1)), fiber
);
case 1:
return (fiber = describeNativeComponentFrame(fiber.type, !0)), fiber;
default:
return "";
}
}
function getStackByFiberInDevAndProd(workInProgress) {
try {
var info = "";
do
(info += describeFiber(workInProgress)),
(workInProgress = workInProgress.return);
while (workInProgress);
return info;
} catch (x) {
return "\nError generating stack: " + x.message + "\n" + x.stack;
}
}
var SuspenseException = Error(formatProdErrorMessage(460)),
SuspenseyCommitException = Error(formatProdErrorMessage(474)),
noopSuspenseyCommitThenable = { then: function () {} };
@@ -3710,20 +3721,6 @@ function resolveDefaultProps(Component, baseProps) {
}
return baseProps;
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
if ("object" === typeof value && null !== value) {
var stack = CapturedStacks.get(value);
"string" !== typeof stack &&
((stack = getStackByFiberInDevAndProd(source)),
CapturedStacks.set(value, stack));
} else stack = getStackByFiberInDevAndProd(source);
return { value: value, source: source, stack: stack };
}
function createCapturedValueFromError(value, stack) {
"string" === typeof stack && CapturedStacks.set(value, stack);
return { value: value, source: null, stack: stack };
}
"function" === typeof reportError
? reportError
: function (error) {
@@ -3828,93 +3825,93 @@ function throwException(
"object" === typeof value &&
"function" === typeof value.then
) {
returnFiber = value;
enableLazyContextPropagation &&
((value = sourceFiber.alternate),
null !== value &&
propagateParentContextChanges(value, sourceFiber, rootRenderLanes, !0));
value = suspenseHandlerStackCursor.current;
if (null !== value) {
switch (value.tag) {
((returnFiber = sourceFiber.alternate),
null !== returnFiber &&
propagateParentContextChanges(
returnFiber,
sourceFiber,
rootRenderLanes,
!0
));
returnFiber = suspenseHandlerStackCursor.current;
if (null !== returnFiber) {
switch (returnFiber.tag) {
case 13:
return (
null === shellBoundary
? renderDidSuspendDelayIfPossible()
: null === value.alternate &&
: null === returnFiber.alternate &&
0 === workInProgressRootExitStatus &&
(workInProgressRootExitStatus = 3),
(value.flags &= -257),
(value.flags |= 65536),
(value.lanes = rootRenderLanes),
returnFiber === noopSuspenseyCommitThenable
? (value.flags |= 16384)
: ((sourceFiber = value.updateQueue),
(returnFiber.flags &= -257),
(returnFiber.flags |= 65536),
(returnFiber.lanes = rootRenderLanes),
value === noopSuspenseyCommitThenable
? (returnFiber.flags |= 16384)
: ((sourceFiber = returnFiber.updateQueue),
null === sourceFiber
? (value.updateQueue = new Set([returnFiber]))
: sourceFiber.add(returnFiber),
attachPingListener(root, returnFiber, rootRenderLanes)),
? (returnFiber.updateQueue = new Set([value]))
: sourceFiber.add(value),
attachPingListener(root, value, rootRenderLanes)),
!1
);
case 22:
return (
(value.flags |= 65536),
returnFiber === noopSuspenseyCommitThenable
? (value.flags |= 16384)
: ((sourceFiber = value.updateQueue),
(returnFiber.flags |= 65536),
value === noopSuspenseyCommitThenable
? (returnFiber.flags |= 16384)
: ((sourceFiber = returnFiber.updateQueue),
null === sourceFiber
? ((sourceFiber = {
transitions: null,
markerInstances: null,
retryQueue: new Set([returnFiber])
retryQueue: new Set([value])
}),
(value.updateQueue = sourceFiber))
: ((value = sourceFiber.retryQueue),
null === value
? (sourceFiber.retryQueue = new Set([returnFiber]))
: value.add(returnFiber)),
attachPingListener(root, returnFiber, rootRenderLanes)),
(returnFiber.updateQueue = sourceFiber))
: ((returnFiber = sourceFiber.retryQueue),
null === returnFiber
? (sourceFiber.retryQueue = new Set([value]))
: returnFiber.add(value)),
attachPingListener(root, value, rootRenderLanes)),
!1
);
}
throw Error(formatProdErrorMessage(435, value.tag));
throw Error(formatProdErrorMessage(435, returnFiber.tag));
}
attachPingListener(root, returnFiber, rootRenderLanes);
attachPingListener(root, value, rootRenderLanes);
renderDidSuspendDelayIfPossible();
return !1;
}
sourceFiber = value = createCapturedValueAtFiber(value, sourceFiber);
4 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2);
var wrapperError = Error(formatProdErrorMessage(520), { cause: value });
wrapperError = createCapturedValueAtFiber(wrapperError, sourceFiber);
null === workInProgressRootConcurrentErrors
? (workInProgressRootConcurrentErrors = [sourceFiber])
: workInProgressRootConcurrentErrors.push(sourceFiber);
? (workInProgressRootConcurrentErrors = [wrapperError])
: workInProgressRootConcurrentErrors.push(wrapperError);
4 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2);
if (null === returnFiber) return !0;
value = createCapturedValueAtFiber(value, sourceFiber);
do {
switch (returnFiber.tag) {
case 3:
return (
(root = value),
(returnFiber.flags |= 65536),
(rootRenderLanes &= -rootRenderLanes),
(returnFiber.lanes |= rootRenderLanes),
(root = createRootErrorUpdate(
returnFiber.stateNode,
root,
rootRenderLanes
)),
(root = rootRenderLanes & -rootRenderLanes),
(returnFiber.lanes |= root),
(root = createRootErrorUpdate(returnFiber.stateNode, value, root)),
enqueueCapturedUpdate(returnFiber, root),
!1
);
case 1:
sourceFiber = value;
var ctor = returnFiber.type,
instance = returnFiber.stateNode;
if (
((sourceFiber = returnFiber.type),
(wrapperError = returnFiber.stateNode),
0 === (returnFiber.flags & 128) &&
("function" === typeof ctor.getDerivedStateFromError ||
(null !== instance &&
"function" === typeof instance.componentDidCatch &&
(null === legacyErrorBoundariesThatAlreadyFailed ||
!legacyErrorBoundariesThatAlreadyFailed.has(instance))))
("function" === typeof sourceFiber.getDerivedStateFromError ||
(null !== wrapperError &&
"function" === typeof wrapperError.componentDidCatch &&
(null === legacyErrorBoundariesThatAlreadyFailed ||
!legacyErrorBoundariesThatAlreadyFailed.has(wrapperError)))))
)
return (
(returnFiber.flags |= 65536),
@@ -3925,7 +3922,7 @@ function throwException(
rootRenderLanes,
root,
returnFiber,
sourceFiber
value
),
enqueueCapturedUpdate(returnFiber, rootRenderLanes),
!1
@@ -4728,15 +4725,10 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
workInProgress.flags & 256
? (pushPrimaryTreeSuspenseHandler(workInProgress),
(workInProgress.flags &= -257),
(JSCompiler_temp = createCapturedValueFromError(
Error(formatProdErrorMessage(422)),
null
)),
(workInProgress = retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
JSCompiler_temp
renderLanes
)))
: null !== workInProgress.memoizedState
? (reuseSuspenseHandlerOnStack(workInProgress),
@@ -4781,12 +4773,14 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
(nextProps = Error(formatProdErrorMessage(419))),
(nextProps.stack = ""),
(nextProps.digest = JSCompiler_temp),
(JSCompiler_temp = createCapturedValueFromError(nextProps, null)),
(JSCompiler_temp = { value: nextProps, source: null, stack: null }),
null === hydrationErrors
? (hydrationErrors = [JSCompiler_temp])
: hydrationErrors.push(JSCompiler_temp),
(workInProgress = retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
JSCompiler_temp
renderLanes
));
else if (
(enableLazyContextPropagation &&
@@ -4854,8 +4848,7 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
workInProgress = retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
null
renderLanes
);
} else
shim$2()
@@ -5010,13 +5003,8 @@ function mountWorkInProgressOffscreenFiber(offscreenProps, mode) {
function retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
recoverableError
renderLanes
) {
null !== recoverableError &&
(null === hydrationErrors
? (hydrationErrors = [recoverableError])
: hydrationErrors.push(recoverableError));
reconcileChildFibers(workInProgress, current.child, null, renderLanes);
current = mountSuspensePrimaryChildren(
workInProgress,
@@ -6118,14 +6106,14 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
break;
case "collapsed":
lastTailNode = renderState.tail;
for (var lastTailNode$75 = null; null !== lastTailNode; )
null !== lastTailNode.alternate && (lastTailNode$75 = lastTailNode),
for (var lastTailNode$73 = null; null !== lastTailNode; )
null !== lastTailNode.alternate && (lastTailNode$73 = lastTailNode),
(lastTailNode = lastTailNode.sibling);
null === lastTailNode$75
null === lastTailNode$73
? hasRenderedATailFallback || null === renderState.tail
? (renderState.tail = null)
: (renderState.tail.sibling = null)
: (lastTailNode$75.sibling = null);
: (lastTailNode$73.sibling = null);
}
}
function bubbleProperties(completedWork) {
@@ -6135,19 +6123,19 @@ function bubbleProperties(completedWork) {
newChildLanes = 0,
subtreeFlags = 0;
if (didBailout)
for (var child$76 = completedWork.child; null !== child$76; )
(newChildLanes |= child$76.lanes | child$76.childLanes),
(subtreeFlags |= child$76.subtreeFlags & 31457280),
(subtreeFlags |= child$76.flags & 31457280),
(child$76.return = completedWork),
(child$76 = child$76.sibling);
for (var child$74 = completedWork.child; null !== child$74; )
(newChildLanes |= child$74.lanes | child$74.childLanes),
(subtreeFlags |= child$74.subtreeFlags & 31457280),
(subtreeFlags |= child$74.flags & 31457280),
(child$74.return = completedWork),
(child$74 = child$74.sibling);
else
for (child$76 = completedWork.child; null !== child$76; )
(newChildLanes |= child$76.lanes | child$76.childLanes),
(subtreeFlags |= child$76.subtreeFlags),
(subtreeFlags |= child$76.flags),
(child$76.return = completedWork),
(child$76 = child$76.sibling);
for (child$74 = completedWork.child; null !== child$74; )
(newChildLanes |= child$74.lanes | child$74.childLanes),
(subtreeFlags |= child$74.subtreeFlags),
(subtreeFlags |= child$74.flags),
(child$74.return = completedWork),
(child$74 = child$74.sibling);
completedWork.subtreeFlags |= subtreeFlags;
completedWork.childLanes = newChildLanes;
return didBailout;
@@ -6318,11 +6306,11 @@ function completeWork(current, workInProgress, renderLanes) {
null !== newProps.alternate.memoizedState &&
null !== newProps.alternate.memoizedState.cachePool &&
(instance = newProps.alternate.memoizedState.cachePool.pool);
var cache$80 = null;
var cache$78 = null;
null !== newProps.memoizedState &&
null !== newProps.memoizedState.cachePool &&
(cache$80 = newProps.memoizedState.cachePool.pool);
cache$80 !== instance && (newProps.flags |= 2048);
(cache$78 = newProps.memoizedState.cachePool.pool);
cache$78 !== instance && (newProps.flags |= 2048);
}
renderLanes !== current &&
(enableTransitionTracing && (workInProgress.child.flags |= 2048),
@@ -6350,8 +6338,8 @@ function completeWork(current, workInProgress, renderLanes) {
instance = workInProgress.memoizedState;
if (null === instance) return bubbleProperties(workInProgress), null;
newProps = 0 !== (workInProgress.flags & 128);
cache$80 = instance.rendering;
if (null === cache$80)
cache$78 = instance.rendering;
if (null === cache$78)
if (newProps) cutOffTailIfNeeded(instance, !1);
else {
if (
@@ -6359,11 +6347,11 @@ function completeWork(current, workInProgress, renderLanes) {
(null !== current && 0 !== (current.flags & 128))
)
for (current = workInProgress.child; null !== current; ) {
cache$80 = findFirstSuspended(current);
if (null !== cache$80) {
cache$78 = findFirstSuspended(current);
if (null !== cache$78) {
workInProgress.flags |= 128;
cutOffTailIfNeeded(instance, !1);
current = cache$80.updateQueue;
current = cache$78.updateQueue;
workInProgress.updateQueue = current;
scheduleRetryEffect(workInProgress, current);
workInProgress.subtreeFlags = 0;
@@ -6388,7 +6376,7 @@ function completeWork(current, workInProgress, renderLanes) {
}
else {
if (!newProps)
if (((current = findFirstSuspended(cache$80)), null !== current)) {
if (((current = findFirstSuspended(cache$78)), null !== current)) {
if (
((workInProgress.flags |= 128),
(newProps = !0),
@@ -6398,7 +6386,7 @@ function completeWork(current, workInProgress, renderLanes) {
cutOffTailIfNeeded(instance, !0),
null === instance.tail &&
"hidden" === instance.tailMode &&
!cache$80.alternate)
!cache$78.alternate)
)
return bubbleProperties(workInProgress), null;
} else
@@ -6410,13 +6398,13 @@ function completeWork(current, workInProgress, renderLanes) {
cutOffTailIfNeeded(instance, !1),
(workInProgress.lanes = 4194304));
instance.isBackwards
? ((cache$80.sibling = workInProgress.child),
(workInProgress.child = cache$80))
? ((cache$78.sibling = workInProgress.child),
(workInProgress.child = cache$78))
: ((current = instance.last),
null !== current
? (current.sibling = cache$80)
: (workInProgress.child = cache$80),
(instance.last = cache$80));
? (current.sibling = cache$78)
: (workInProgress.child = cache$78),
(instance.last = cache$78));
}
if (null !== instance.tail)
return (
@@ -6679,8 +6667,8 @@ function safelyDetachRef(current, nearestMountedAncestor) {
else if ("function" === typeof ref)
try {
ref(null);
} catch (error$97) {
captureCommitPhaseError(current, nearestMountedAncestor, error$97);
} catch (error$95) {
captureCommitPhaseError(current, nearestMountedAncestor, error$95);
}
else ref.current = null;
}
@@ -6884,11 +6872,11 @@ function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork) {
current,
finishedRoot.__reactInternalSnapshotBeforeUpdate
);
} catch (error$98) {
} catch (error$96) {
captureCommitPhaseError(
finishedWork,
finishedWork.return,
error$98
error$96
);
}
}
@@ -7468,8 +7456,8 @@ function commitMutationEffectsOnFiber(finishedWork, root) {
}
try {
commitHookEffectListUnmount(5, finishedWork, finishedWork.return);
} catch (error$106) {
captureCommitPhaseError(finishedWork, finishedWork.return, error$106);
} catch (error$104) {
captureCommitPhaseError(finishedWork, finishedWork.return, error$104);
}
}
break;
@@ -7503,8 +7491,8 @@ function commitMutationEffectsOnFiber(finishedWork, root) {
finishedWork.updateQueue = null;
try {
flags._applyProps(flags, newProps, current);
} catch (error$109) {
captureCommitPhaseError(finishedWork, finishedWork.return, error$109);
} catch (error$107) {
captureCommitPhaseError(finishedWork, finishedWork.return, error$107);
}
}
break;
@@ -7540,8 +7528,8 @@ function commitMutationEffectsOnFiber(finishedWork, root) {
null !== retryQueue && suspenseCallback(new Set(retryQueue));
}
}
} catch (error$111) {
captureCommitPhaseError(finishedWork, finishedWork.return, error$111);
} catch (error$109) {
captureCommitPhaseError(finishedWork, finishedWork.return, error$109);
}
flags = finishedWork.updateQueue;
null !== flags &&
@@ -7678,12 +7666,12 @@ function commitReconciliationEffects(finishedWork) {
break;
case 3:
case 4:
var parent$101 = JSCompiler_inline_result.stateNode.containerInfo,
before$102 = getHostSibling(finishedWork);
var parent$99 = JSCompiler_inline_result.stateNode.containerInfo,
before$100 = getHostSibling(finishedWork);
insertOrAppendPlacementNodeIntoContainer(
finishedWork,
before$102,
parent$101
before$100,
parent$99
);
break;
default:
@@ -8133,9 +8121,9 @@ function recursivelyTraverseReconnectPassiveEffects(
);
break;
case 22:
var instance$117 = finishedWork.stateNode;
var instance$115 = finishedWork.stateNode;
null !== finishedWork.memoizedState
? instance$117._visibility & 4
? instance$115._visibility & 4
? recursivelyTraverseReconnectPassiveEffects(
finishedRoot,
finishedWork,
@@ -8147,7 +8135,7 @@ function recursivelyTraverseReconnectPassiveEffects(
finishedRoot,
finishedWork
)
: ((instance$117._visibility |= 4),
: ((instance$115._visibility |= 4),
recursivelyTraverseReconnectPassiveEffects(
finishedRoot,
finishedWork,
@@ -8160,7 +8148,7 @@ function recursivelyTraverseReconnectPassiveEffects(
commitOffscreenPassiveMountEffects(
finishedWork.alternate,
finishedWork,
instance$117
instance$115
);
break;
case 24:
@@ -9069,8 +9057,8 @@ function renderRootSync(root, lanes) {
}
workLoopSync();
break;
} catch (thrownValue$125) {
handleThrow(root, thrownValue$125);
} catch (thrownValue$123) {
handleThrow(root, thrownValue$123);
}
while (1);
lanes && root.shellSuspendCounter++;
@@ -9175,8 +9163,8 @@ function renderRootConcurrent(root, lanes) {
}
workLoopConcurrent();
break;
} catch (thrownValue$127) {
handleThrow(root, thrownValue$127);
} catch (thrownValue$125) {
handleThrow(root, thrownValue$125);
}
while (1);
resetContextDependencies();
@@ -10152,19 +10140,19 @@ var slice = Array.prototype.slice,
};
return Text;
})(React.Component),
devToolsConfig$jscomp$inline_1090 = {
devToolsConfig$jscomp$inline_1086 = {
findFiberByHostInstance: function () {
return null;
},
bundleType: 0,
version: "19.0.0-www-modern-b87e0d5e",
version: "19.0.0-www-modern-c8d23bec",
rendererPackageName: "react-art"
};
var internals$jscomp$inline_1296 = {
bundleType: devToolsConfig$jscomp$inline_1090.bundleType,
version: devToolsConfig$jscomp$inline_1090.version,
rendererPackageName: devToolsConfig$jscomp$inline_1090.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_1090.rendererConfig,
var internals$jscomp$inline_1298 = {
bundleType: devToolsConfig$jscomp$inline_1086.bundleType,
version: devToolsConfig$jscomp$inline_1086.version,
rendererPackageName: devToolsConfig$jscomp$inline_1086.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_1086.rendererConfig,
overrideHookState: null,
overrideHookStateDeletePath: null,
overrideHookStateRenamePath: null,
@@ -10181,26 +10169,26 @@ var internals$jscomp$inline_1296 = {
return null === fiber ? null : fiber.stateNode;
},
findFiberByHostInstance:
devToolsConfig$jscomp$inline_1090.findFiberByHostInstance ||
devToolsConfig$jscomp$inline_1086.findFiberByHostInstance ||
emptyFindFiberByHostInstance,
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-www-modern-b87e0d5e"
reconcilerVersion: "19.0.0-www-modern-c8d23bec"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1297 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
var hook$jscomp$inline_1299 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
if (
!hook$jscomp$inline_1297.isDisabled &&
hook$jscomp$inline_1297.supportsFiber
!hook$jscomp$inline_1299.isDisabled &&
hook$jscomp$inline_1299.supportsFiber
)
try {
(rendererID = hook$jscomp$inline_1297.inject(
internals$jscomp$inline_1296
(rendererID = hook$jscomp$inline_1299.inject(
internals$jscomp$inline_1298
)),
(injectedHook = hook$jscomp$inline_1297);
(injectedHook = hook$jscomp$inline_1299);
} catch (err) {}
}
var Path = Mode$1.Path;
+146 -120
View File
@@ -7875,6 +7875,43 @@ if (__DEV__) {
return currentState.isDehydrated;
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
// Intentionally not using it yet to derisk the initial implementation, because
// the way we push/pop these values is a bit unusual. If there's a mistake, I'd
// rather the ids be wrong than crash the whole reconciler.
@@ -8943,6 +8980,11 @@ if (__DEV__) {
return false;
}
var HydrationMismatchException = new Error(
"Hydration Mismatch Exception: This is not a real error, and should not leak into " +
"userspace. If you're seeing this, it's likely a bug in React."
);
function throwOnHydrationMismatch(fiber) {
var diff = "";
@@ -8957,7 +8999,7 @@ if (__DEV__) {
}
}
throw new Error(
var error = new Error(
"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:\n" +
"\n" +
"- A server/client branch `if (typeof window !== 'undefined')`.\n" +
@@ -8971,6 +9013,8 @@ if (__DEV__) {
"https://react.dev/link/hydration-mismatch" +
diff
);
queueHydrationError(createCapturedValueAtFiber(error, fiber));
throw HydrationMismatchException;
}
function claimHydratableSingleton(fiber) {
@@ -9032,7 +9076,7 @@ if (__DEV__) {
warnNonHydratedInstance(fiber, nextInstance);
}
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -9056,7 +9100,7 @@ if (__DEV__) {
warnNonHydratedInstance(fiber, nextInstance);
}
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -9069,7 +9113,7 @@ if (__DEV__) {
if (!nextInstance || !tryHydrateSuspense(fiber, nextInstance)) {
warnNonHydratedInstance(fiber, nextInstance);
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -9097,7 +9141,7 @@ if (__DEV__) {
// rendering. We don't bother to check if we're in a concurrent root because
// useActionState is a new API, so backwards compat is not an issue.
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
return false;
}
@@ -9112,7 +9156,7 @@ if (__DEV__) {
);
if (!didHydrate && favorSafetyOverHydrationPerf) {
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -9179,7 +9223,7 @@ if (__DEV__) {
);
if (!didHydrate && favorSafetyOverHydrationPerf) {
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -9273,7 +9317,7 @@ if (__DEV__) {
if (nextInstance) {
warnIfUnhydratedTailNodes(fiber);
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -15231,7 +15275,9 @@ if (__DEV__) {
// matches this hook instance.
if (ssrFormState !== null) {
var isMatching = tryToClaimNextHydratableFormMarkerInstance();
var isMatching = tryToClaimNextHydratableFormMarkerInstance(
currentlyRenderingFiber$1
);
if (isMatching) {
initialState = ssrFormState[0];
@@ -19147,43 +19193,6 @@ if (__DEV__) {
return baseProps;
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
var reportGlobalError =
typeof reportError === "function" // In modern browsers, reportError will dispatch an error event,
? // emulating an uncaught JavaScript error.
@@ -19809,13 +19818,65 @@ if (__DEV__) {
); // Even though the user may not be affected by this error, we should
// still log it so it can be fixed.
queueHydrationError(createCapturedValueAtFiber(value, sourceFiber));
if (value !== HydrationMismatchException) {
var _wrapperError = new Error(
"There was an error while hydrating but React was able to recover by " +
"instead client rendering from the nearest Suspense boundary.",
{
cause: value
}
);
queueHydrationError(
createCapturedValueAtFiber(_wrapperError, sourceFiber)
);
}
return false;
} else {
if (value !== HydrationMismatchException) {
var _wrapperError2 = new Error(
"There was an error while hydrating but React was able to recover by " +
"instead client rendering the entire root.",
{
cause: value
}
);
queueHydrationError(
createCapturedValueAtFiber(_wrapperError2, sourceFiber)
);
}
var _workInProgress = root.current.alternate; // Schedule an update at the root to log the error but this shouldn't
// actually happen because we should recover.
_workInProgress.flags |= ShouldCapture;
var lane = pickArbitraryLane(rootRenderLanes);
_workInProgress.lanes = mergeLanes(_workInProgress.lanes, lane);
var rootErrorInfo = createCapturedValueAtFiber(value, sourceFiber);
var update = createRootErrorUpdate(
_workInProgress.stateNode,
rootErrorInfo, // This should never actually get logged due to the recovery.
lane
);
enqueueCapturedUpdate(_workInProgress, update);
renderDidError();
return false;
}
}
value = createCapturedValueAtFiber(value, sourceFiber);
renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start
var wrapperError = new Error(
"There was an error during concurrent rendering but React was able to recover by " +
"instead synchronously rendering the entire root.",
{
cause: value
}
);
queueConcurrentError(
createCapturedValueAtFiber(wrapperError, sourceFiber)
);
renderDidError(); // We didn't find a boundary that could handle this type of exception. Start
// over and traverse parent path again, this time treating the exception
// as an error.
@@ -19825,34 +19886,30 @@ if (__DEV__) {
return true;
}
var errorInfo = createCapturedValueAtFiber(value, sourceFiber);
var workInProgress = returnFiber;
do {
switch (workInProgress.tag) {
case HostRoot: {
var _errorInfo = value;
workInProgress.flags |= ShouldCapture;
var lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
var update = createRootErrorUpdate(
var _lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane);
var _update = createRootErrorUpdate(
workInProgress.stateNode,
_errorInfo,
lane
errorInfo,
_lane
);
enqueueCapturedUpdate(workInProgress, update);
enqueueCapturedUpdate(workInProgress, _update);
return false;
}
case ClassComponent:
if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) {
// If we're hydrating and got here, it means that we didn't find a suspense
// boundary above so it's a root error. In this case we shouldn't let the
// error boundary capture it because it'll just try to hydrate the error state.
// Instead we let it bubble to the root and let the recover pass handle it.
break;
} // Capture and retry
var errorInfo = value;
// Capture and retry
var ctor = workInProgress.type;
var instance = workInProgress.stateNode;
@@ -19865,19 +19922,19 @@ if (__DEV__) {
) {
workInProgress.flags |= ShouldCapture;
var _lane = pickArbitraryLane(rootRenderLanes);
var _lane2 = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane2); // Schedule the error boundary to re-render using updated state
var _update = createClassErrorUpdate(_lane);
var _update2 = createClassErrorUpdate(_lane2);
initializeClassErrorUpdate(
_update,
_update2,
root,
workInProgress,
errorInfo
);
enqueueCapturedUpdate(workInProgress, _update);
enqueueCapturedUpdate(workInProgress, _update2);
return false;
}
@@ -21287,37 +21344,27 @@ if (__DEV__) {
if (workInProgress.flags & ForceClientRender) {
// Something errored during a previous attempt to hydrate the shell, so we
// forced a client render.
var recoverableError = createCapturedValueAtFiber(
new Error(
"There was an error while hydrating. Because the error happened outside " +
"of a Suspense boundary, the entire root will switch to " +
"client rendering."
),
workInProgress
);
// forced a client render. We should have a recoverable error already scheduled.
return mountHostRootWithoutHydrating(
current,
workInProgress,
nextChildren,
renderLanes,
recoverableError
renderLanes
);
} else if (nextChildren !== prevChildren) {
var _recoverableError = createCapturedValueAtFiber(
var recoverableError = createCapturedValueAtFiber(
new Error(
"This root received an early update, before anything was able " +
"hydrate. Switched the entire root to client rendering."
),
workInProgress
);
queueHydrationError(recoverableError);
return mountHostRootWithoutHydrating(
current,
workInProgress,
nextChildren,
renderLanes,
_recoverableError
renderLanes
);
} else {
// The outermost shell has not hydrated yet. Start hydrating.
@@ -21365,12 +21412,10 @@ if (__DEV__) {
current,
workInProgress,
nextChildren,
renderLanes,
recoverableError
renderLanes
) {
// Revert to client rendering.
resetHydrationState();
queueHydrationError(recoverableError);
workInProgress.flags |= ForceClientRender;
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
return workInProgress.child;
@@ -22330,20 +22375,12 @@ if (__DEV__) {
function retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
recoverableError
renderLanes
) {
// Falling back to client rendering. Because this has performance
// implications, it's considered a recoverable error, even though the user
// likely won't observe anything wrong with the UI.
//
// The error is passed in as an argument to enforce that every caller provide
// a custom message, or explicitly opt out (currently the only path that opts
// out is legacy mode; every concurrent path provides an error).
if (recoverableError !== null) {
queueHydrationError(recoverableError);
} // This will add the old fiber to the deletion list
// This will add the old fiber to the deletion list
reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
var nextProps = workInProgress.pendingProps;
@@ -22461,9 +22498,7 @@ if (__DEV__) {
message = _getSuspenseInstanceF.message;
stack = _getSuspenseInstanceF.stack;
componentStack = _getSuspenseInstanceF.componentStack;
}
var capturedValue = null; // TODO: Figure out a better signal than encoding a magic digest value.
} // TODO: Figure out a better signal than encoding a magic digest value.
{
var error;
@@ -22481,17 +22516,17 @@ if (__DEV__) {
error.stack = stack || "";
error.digest = digest;
capturedValue = createCapturedValueFromError(
var capturedValue = createCapturedValueFromError(
error,
componentStack === undefined ? null : componentStack
);
queueHydrationError(capturedValue);
}
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
capturedValue
renderLanes
);
}
@@ -22566,8 +22601,7 @@ if (__DEV__) {
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
null
renderLanes
);
} else if (isSuspenseInstancePending(suspenseInstance)) {
// This component is still pending more data from the server, so we can't hydrate its
@@ -22612,22 +22646,13 @@ if (__DEV__) {
// something either suspended or errored.
if (workInProgress.flags & ForceClientRender) {
// Something errored during hydration. Try again without hydrating.
// The error should've already been logged in throwException.
pushPrimaryTreeSuspenseHandler(workInProgress);
workInProgress.flags &= ~ForceClientRender;
var _capturedValue = createCapturedValueFromError(
new Error(
"There was an error while hydrating this Suspense boundary. " +
"Switched to client rendering."
),
null
);
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
_capturedValue
renderLanes
);
} else if (workInProgress.memoizedState !== null) {
// Something suspended and we should still be in dehydrated mode.
@@ -32779,11 +32804,12 @@ if (__DEV__) {
);
}
}
function renderDidError(error) {
function renderDidError() {
if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
workInProgressRootExitStatus = RootErrored;
}
}
function queueConcurrentError(error) {
if (workInProgressRootConcurrentErrors === null) {
workInProgressRootConcurrentErrors = [error];
} else {
@@ -36187,7 +36213,7 @@ if (__DEV__) {
return root;
}
var ReactVersion = "19.0.0-www-classic-bf989094";
var ReactVersion = "19.0.0-www-classic-cd5ebeba";
function createPortal$1(
children,
+146 -120
View File
@@ -18129,6 +18129,43 @@ if (__DEV__) {
return currentState.isDehydrated;
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
// Intentionally not using it yet to derisk the initial implementation, because
// the way we push/pop these values is a bit unusual. If there's a mistake, I'd
// rather the ids be wrong than crash the whole reconciler.
@@ -19197,6 +19234,11 @@ if (__DEV__) {
return false;
}
var HydrationMismatchException = new Error(
"Hydration Mismatch Exception: This is not a real error, and should not leak into " +
"userspace. If you're seeing this, it's likely a bug in React."
);
function throwOnHydrationMismatch(fiber) {
var diff = "";
@@ -19211,7 +19253,7 @@ if (__DEV__) {
}
}
throw new Error(
var error = new Error(
"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:\n" +
"\n" +
"- A server/client branch `if (typeof window !== 'undefined')`.\n" +
@@ -19225,6 +19267,8 @@ if (__DEV__) {
"https://react.dev/link/hydration-mismatch" +
diff
);
queueHydrationError(createCapturedValueAtFiber(error, fiber));
throw HydrationMismatchException;
}
function claimHydratableSingleton(fiber) {
@@ -19286,7 +19330,7 @@ if (__DEV__) {
warnNonHydratedInstance(fiber, nextInstance);
}
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -19310,7 +19354,7 @@ if (__DEV__) {
warnNonHydratedInstance(fiber, nextInstance);
}
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -19323,7 +19367,7 @@ if (__DEV__) {
if (!nextInstance || !tryHydrateSuspense(fiber, nextInstance)) {
warnNonHydratedInstance(fiber, nextInstance);
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -19351,7 +19395,7 @@ if (__DEV__) {
// rendering. We don't bother to check if we're in a concurrent root because
// useActionState is a new API, so backwards compat is not an issue.
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
return false;
}
@@ -19366,7 +19410,7 @@ if (__DEV__) {
);
if (!didHydrate && favorSafetyOverHydrationPerf) {
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -19433,7 +19477,7 @@ if (__DEV__) {
);
if (!didHydrate && favorSafetyOverHydrationPerf) {
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -19527,7 +19571,7 @@ if (__DEV__) {
if (nextInstance) {
warnIfUnhydratedTailNodes(fiber);
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -25432,7 +25476,9 @@ if (__DEV__) {
// matches this hook instance.
if (ssrFormState !== null) {
var isMatching = tryToClaimNextHydratableFormMarkerInstance();
var isMatching = tryToClaimNextHydratableFormMarkerInstance(
currentlyRenderingFiber$1
);
if (isMatching) {
initialState = ssrFormState[0];
@@ -29307,43 +29353,6 @@ if (__DEV__) {
return baseProps;
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
var ReactCurrentActQueue$2 = ReactSharedInternals.ReactCurrentActQueue; // Side-channel since I'm not sure we want to make this part of the public API
var componentName = null;
@@ -29834,13 +29843,65 @@ if (__DEV__) {
); // Even though the user may not be affected by this error, we should
// still log it so it can be fixed.
queueHydrationError(createCapturedValueAtFiber(value, sourceFiber));
if (value !== HydrationMismatchException) {
var _wrapperError = new Error(
"There was an error while hydrating but React was able to recover by " +
"instead client rendering from the nearest Suspense boundary.",
{
cause: value
}
);
queueHydrationError(
createCapturedValueAtFiber(_wrapperError, sourceFiber)
);
}
return false;
} else {
if (value !== HydrationMismatchException) {
var _wrapperError2 = new Error(
"There was an error while hydrating but React was able to recover by " +
"instead client rendering the entire root.",
{
cause: value
}
);
queueHydrationError(
createCapturedValueAtFiber(_wrapperError2, sourceFiber)
);
}
var _workInProgress = root.current.alternate; // Schedule an update at the root to log the error but this shouldn't
// actually happen because we should recover.
_workInProgress.flags |= ShouldCapture;
var lane = pickArbitraryLane(rootRenderLanes);
_workInProgress.lanes = mergeLanes(_workInProgress.lanes, lane);
var rootErrorInfo = createCapturedValueAtFiber(value, sourceFiber);
var update = createRootErrorUpdate(
_workInProgress.stateNode,
rootErrorInfo, // This should never actually get logged due to the recovery.
lane
);
enqueueCapturedUpdate(_workInProgress, update);
renderDidError();
return false;
}
}
value = createCapturedValueAtFiber(value, sourceFiber);
renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start
var wrapperError = new Error(
"There was an error during concurrent rendering but React was able to recover by " +
"instead synchronously rendering the entire root.",
{
cause: value
}
);
queueConcurrentError(
createCapturedValueAtFiber(wrapperError, sourceFiber)
);
renderDidError(); // We didn't find a boundary that could handle this type of exception. Start
// over and traverse parent path again, this time treating the exception
// as an error.
@@ -29850,34 +29911,30 @@ if (__DEV__) {
return true;
}
var errorInfo = createCapturedValueAtFiber(value, sourceFiber);
var workInProgress = returnFiber;
do {
switch (workInProgress.tag) {
case HostRoot: {
var _errorInfo = value;
workInProgress.flags |= ShouldCapture;
var lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
var update = createRootErrorUpdate(
var _lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane);
var _update = createRootErrorUpdate(
workInProgress.stateNode,
_errorInfo,
lane
errorInfo,
_lane
);
enqueueCapturedUpdate(workInProgress, update);
enqueueCapturedUpdate(workInProgress, _update);
return false;
}
case ClassComponent:
if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) {
// If we're hydrating and got here, it means that we didn't find a suspense
// boundary above so it's a root error. In this case we shouldn't let the
// error boundary capture it because it'll just try to hydrate the error state.
// Instead we let it bubble to the root and let the recover pass handle it.
break;
} // Capture and retry
var errorInfo = value;
// Capture and retry
var ctor = workInProgress.type;
var instance = workInProgress.stateNode;
@@ -29890,19 +29947,19 @@ if (__DEV__) {
) {
workInProgress.flags |= ShouldCapture;
var _lane = pickArbitraryLane(rootRenderLanes);
var _lane2 = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane2); // Schedule the error boundary to re-render using updated state
var _update = createClassErrorUpdate(_lane);
var _update2 = createClassErrorUpdate(_lane2);
initializeClassErrorUpdate(
_update,
_update2,
root,
workInProgress,
errorInfo
);
enqueueCapturedUpdate(workInProgress, _update);
enqueueCapturedUpdate(workInProgress, _update2);
return false;
}
@@ -31251,37 +31308,27 @@ if (__DEV__) {
if (workInProgress.flags & ForceClientRender) {
// Something errored during a previous attempt to hydrate the shell, so we
// forced a client render.
var recoverableError = createCapturedValueAtFiber(
new Error(
"There was an error while hydrating. Because the error happened outside " +
"of a Suspense boundary, the entire root will switch to " +
"client rendering."
),
workInProgress
);
// forced a client render. We should have a recoverable error already scheduled.
return mountHostRootWithoutHydrating(
current,
workInProgress,
nextChildren,
renderLanes,
recoverableError
renderLanes
);
} else if (nextChildren !== prevChildren) {
var _recoverableError = createCapturedValueAtFiber(
var recoverableError = createCapturedValueAtFiber(
new Error(
"This root received an early update, before anything was able " +
"hydrate. Switched the entire root to client rendering."
),
workInProgress
);
queueHydrationError(recoverableError);
return mountHostRootWithoutHydrating(
current,
workInProgress,
nextChildren,
renderLanes,
_recoverableError
renderLanes
);
} else {
// The outermost shell has not hydrated yet. Start hydrating.
@@ -31329,12 +31376,10 @@ if (__DEV__) {
current,
workInProgress,
nextChildren,
renderLanes,
recoverableError
renderLanes
) {
// Revert to client rendering.
resetHydrationState();
queueHydrationError(recoverableError);
workInProgress.flags |= ForceClientRender;
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
return workInProgress.child;
@@ -32192,20 +32237,12 @@ if (__DEV__) {
function retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
recoverableError
renderLanes
) {
// Falling back to client rendering. Because this has performance
// implications, it's considered a recoverable error, even though the user
// likely won't observe anything wrong with the UI.
//
// The error is passed in as an argument to enforce that every caller provide
// a custom message, or explicitly opt out (currently the only path that opts
// out is legacy mode; every concurrent path provides an error).
if (recoverableError !== null) {
queueHydrationError(recoverableError);
} // This will add the old fiber to the deletion list
// This will add the old fiber to the deletion list
reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
var nextProps = workInProgress.pendingProps;
@@ -32323,9 +32360,7 @@ if (__DEV__) {
message = _getSuspenseInstanceF.message;
stack = _getSuspenseInstanceF.stack;
componentStack = _getSuspenseInstanceF.componentStack;
}
var capturedValue = null; // TODO: Figure out a better signal than encoding a magic digest value.
} // TODO: Figure out a better signal than encoding a magic digest value.
{
var error;
@@ -32343,17 +32378,17 @@ if (__DEV__) {
error.stack = stack || "";
error.digest = digest;
capturedValue = createCapturedValueFromError(
var capturedValue = createCapturedValueFromError(
error,
componentStack === undefined ? null : componentStack
);
queueHydrationError(capturedValue);
}
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
capturedValue
renderLanes
);
}
@@ -32428,8 +32463,7 @@ if (__DEV__) {
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
null
renderLanes
);
} else if (isSuspenseInstancePending(suspenseInstance)) {
// This component is still pending more data from the server, so we can't hydrate its
@@ -32474,22 +32508,13 @@ if (__DEV__) {
// something either suspended or errored.
if (workInProgress.flags & ForceClientRender) {
// Something errored during hydration. Try again without hydrating.
// The error should've already been logged in throwException.
pushPrimaryTreeSuspenseHandler(workInProgress);
workInProgress.flags &= ~ForceClientRender;
var _capturedValue = createCapturedValueFromError(
new Error(
"There was an error while hydrating this Suspense boundary. " +
"Switched to client rendering."
),
null
);
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
_capturedValue
renderLanes
);
} else if (workInProgress.memoizedState !== null) {
// Something suspended and we should still be in dehydrated mode.
@@ -42381,11 +42406,12 @@ if (__DEV__) {
);
}
}
function renderDidError(error) {
function renderDidError() {
if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
workInProgressRootExitStatus = RootErrored;
}
}
function queueConcurrentError(error) {
if (workInProgressRootConcurrentErrors === null) {
workInProgressRootConcurrentErrors = [error];
} else {
@@ -45681,7 +45707,7 @@ if (__DEV__) {
return root;
}
var ReactVersion = "19.0.0-www-modern-232b2124";
var ReactVersion = "19.0.0-www-modern-b12aa191";
function createPortal$1(
children,
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -8012,6 +8012,43 @@ if (__DEV__) {
return currentState.isDehydrated;
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
// Intentionally not using it yet to derisk the initial implementation, because
// the way we push/pop these values is a bit unusual. If there's a mistake, I'd
// rather the ids be wrong than crash the whole reconciler.
@@ -9080,6 +9117,11 @@ if (__DEV__) {
return false;
}
var HydrationMismatchException = new Error(
"Hydration Mismatch Exception: This is not a real error, and should not leak into " +
"userspace. If you're seeing this, it's likely a bug in React."
);
function throwOnHydrationMismatch(fiber) {
var diff = "";
@@ -9094,7 +9136,7 @@ if (__DEV__) {
}
}
throw new Error(
var error = new Error(
"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:\n" +
"\n" +
"- A server/client branch `if (typeof window !== 'undefined')`.\n" +
@@ -9108,6 +9150,8 @@ if (__DEV__) {
"https://react.dev/link/hydration-mismatch" +
diff
);
queueHydrationError(createCapturedValueAtFiber(error, fiber));
throw HydrationMismatchException;
}
function claimHydratableSingleton(fiber) {
@@ -9169,7 +9213,7 @@ if (__DEV__) {
warnNonHydratedInstance(fiber, nextInstance);
}
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -9193,7 +9237,7 @@ if (__DEV__) {
warnNonHydratedInstance(fiber, nextInstance);
}
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -9206,7 +9250,7 @@ if (__DEV__) {
if (!nextInstance || !tryHydrateSuspense(fiber, nextInstance)) {
warnNonHydratedInstance(fiber, nextInstance);
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -9234,7 +9278,7 @@ if (__DEV__) {
// rendering. We don't bother to check if we're in a concurrent root because
// useActionState is a new API, so backwards compat is not an issue.
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
return false;
}
@@ -9249,7 +9293,7 @@ if (__DEV__) {
);
if (!didHydrate && favorSafetyOverHydrationPerf) {
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -9316,7 +9360,7 @@ if (__DEV__) {
);
if (!didHydrate && favorSafetyOverHydrationPerf) {
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -9410,7 +9454,7 @@ if (__DEV__) {
if (nextInstance) {
warnIfUnhydratedTailNodes(fiber);
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -15368,7 +15412,9 @@ if (__DEV__) {
// matches this hook instance.
if (ssrFormState !== null) {
var isMatching = tryToClaimNextHydratableFormMarkerInstance();
var isMatching = tryToClaimNextHydratableFormMarkerInstance(
currentlyRenderingFiber$1
);
if (isMatching) {
initialState = ssrFormState[0];
@@ -19284,43 +19330,6 @@ if (__DEV__) {
return baseProps;
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
var reportGlobalError =
typeof reportError === "function" // In modern browsers, reportError will dispatch an error event,
? // emulating an uncaught JavaScript error.
@@ -19946,13 +19955,65 @@ if (__DEV__) {
); // Even though the user may not be affected by this error, we should
// still log it so it can be fixed.
queueHydrationError(createCapturedValueAtFiber(value, sourceFiber));
if (value !== HydrationMismatchException) {
var _wrapperError = new Error(
"There was an error while hydrating but React was able to recover by " +
"instead client rendering from the nearest Suspense boundary.",
{
cause: value
}
);
queueHydrationError(
createCapturedValueAtFiber(_wrapperError, sourceFiber)
);
}
return false;
} else {
if (value !== HydrationMismatchException) {
var _wrapperError2 = new Error(
"There was an error while hydrating but React was able to recover by " +
"instead client rendering the entire root.",
{
cause: value
}
);
queueHydrationError(
createCapturedValueAtFiber(_wrapperError2, sourceFiber)
);
}
var _workInProgress = root.current.alternate; // Schedule an update at the root to log the error but this shouldn't
// actually happen because we should recover.
_workInProgress.flags |= ShouldCapture;
var lane = pickArbitraryLane(rootRenderLanes);
_workInProgress.lanes = mergeLanes(_workInProgress.lanes, lane);
var rootErrorInfo = createCapturedValueAtFiber(value, sourceFiber);
var update = createRootErrorUpdate(
_workInProgress.stateNode,
rootErrorInfo, // This should never actually get logged due to the recovery.
lane
);
enqueueCapturedUpdate(_workInProgress, update);
renderDidError();
return false;
}
}
value = createCapturedValueAtFiber(value, sourceFiber);
renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start
var wrapperError = new Error(
"There was an error during concurrent rendering but React was able to recover by " +
"instead synchronously rendering the entire root.",
{
cause: value
}
);
queueConcurrentError(
createCapturedValueAtFiber(wrapperError, sourceFiber)
);
renderDidError(); // We didn't find a boundary that could handle this type of exception. Start
// over and traverse parent path again, this time treating the exception
// as an error.
@@ -19962,34 +20023,30 @@ if (__DEV__) {
return true;
}
var errorInfo = createCapturedValueAtFiber(value, sourceFiber);
var workInProgress = returnFiber;
do {
switch (workInProgress.tag) {
case HostRoot: {
var _errorInfo = value;
workInProgress.flags |= ShouldCapture;
var lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
var update = createRootErrorUpdate(
var _lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane);
var _update = createRootErrorUpdate(
workInProgress.stateNode,
_errorInfo,
lane
errorInfo,
_lane
);
enqueueCapturedUpdate(workInProgress, update);
enqueueCapturedUpdate(workInProgress, _update);
return false;
}
case ClassComponent:
if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) {
// If we're hydrating and got here, it means that we didn't find a suspense
// boundary above so it's a root error. In this case we shouldn't let the
// error boundary capture it because it'll just try to hydrate the error state.
// Instead we let it bubble to the root and let the recover pass handle it.
break;
} // Capture and retry
var errorInfo = value;
// Capture and retry
var ctor = workInProgress.type;
var instance = workInProgress.stateNode;
@@ -20002,19 +20059,19 @@ if (__DEV__) {
) {
workInProgress.flags |= ShouldCapture;
var _lane = pickArbitraryLane(rootRenderLanes);
var _lane2 = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane2); // Schedule the error boundary to re-render using updated state
var _update = createClassErrorUpdate(_lane);
var _update2 = createClassErrorUpdate(_lane2);
initializeClassErrorUpdate(
_update,
_update2,
root,
workInProgress,
errorInfo
);
enqueueCapturedUpdate(workInProgress, _update);
enqueueCapturedUpdate(workInProgress, _update2);
return false;
}
@@ -21424,37 +21481,27 @@ if (__DEV__) {
if (workInProgress.flags & ForceClientRender) {
// Something errored during a previous attempt to hydrate the shell, so we
// forced a client render.
var recoverableError = createCapturedValueAtFiber(
new Error(
"There was an error while hydrating. Because the error happened outside " +
"of a Suspense boundary, the entire root will switch to " +
"client rendering."
),
workInProgress
);
// forced a client render. We should have a recoverable error already scheduled.
return mountHostRootWithoutHydrating(
current,
workInProgress,
nextChildren,
renderLanes,
recoverableError
renderLanes
);
} else if (nextChildren !== prevChildren) {
var _recoverableError = createCapturedValueAtFiber(
var recoverableError = createCapturedValueAtFiber(
new Error(
"This root received an early update, before anything was able " +
"hydrate. Switched the entire root to client rendering."
),
workInProgress
);
queueHydrationError(recoverableError);
return mountHostRootWithoutHydrating(
current,
workInProgress,
nextChildren,
renderLanes,
_recoverableError
renderLanes
);
} else {
// The outermost shell has not hydrated yet. Start hydrating.
@@ -21502,12 +21549,10 @@ if (__DEV__) {
current,
workInProgress,
nextChildren,
renderLanes,
recoverableError
renderLanes
) {
// Revert to client rendering.
resetHydrationState();
queueHydrationError(recoverableError);
workInProgress.flags |= ForceClientRender;
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
return workInProgress.child;
@@ -22467,20 +22512,12 @@ if (__DEV__) {
function retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
recoverableError
renderLanes
) {
// Falling back to client rendering. Because this has performance
// implications, it's considered a recoverable error, even though the user
// likely won't observe anything wrong with the UI.
//
// The error is passed in as an argument to enforce that every caller provide
// a custom message, or explicitly opt out (currently the only path that opts
// out is legacy mode; every concurrent path provides an error).
if (recoverableError !== null) {
queueHydrationError(recoverableError);
} // This will add the old fiber to the deletion list
// This will add the old fiber to the deletion list
reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
var nextProps = workInProgress.pendingProps;
@@ -22598,9 +22635,7 @@ if (__DEV__) {
message = _getSuspenseInstanceF.message;
stack = _getSuspenseInstanceF.stack;
componentStack = _getSuspenseInstanceF.componentStack;
}
var capturedValue = null; // TODO: Figure out a better signal than encoding a magic digest value.
} // TODO: Figure out a better signal than encoding a magic digest value.
{
var error;
@@ -22618,17 +22653,17 @@ if (__DEV__) {
error.stack = stack || "";
error.digest = digest;
capturedValue = createCapturedValueFromError(
var capturedValue = createCapturedValueFromError(
error,
componentStack === undefined ? null : componentStack
);
queueHydrationError(capturedValue);
}
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
capturedValue
renderLanes
);
}
@@ -22703,8 +22738,7 @@ if (__DEV__) {
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
null
renderLanes
);
} else if (isSuspenseInstancePending(suspenseInstance)) {
// This component is still pending more data from the server, so we can't hydrate its
@@ -22749,22 +22783,13 @@ if (__DEV__) {
// something either suspended or errored.
if (workInProgress.flags & ForceClientRender) {
// Something errored during hydration. Try again without hydrating.
// The error should've already been logged in throwException.
pushPrimaryTreeSuspenseHandler(workInProgress);
workInProgress.flags &= ~ForceClientRender;
var _capturedValue = createCapturedValueFromError(
new Error(
"There was an error while hydrating this Suspense boundary. " +
"Switched to client rendering."
),
null
);
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
_capturedValue
renderLanes
);
} else if (workInProgress.memoizedState !== null) {
// Something suspended and we should still be in dehydrated mode.
@@ -33403,11 +33428,12 @@ if (__DEV__) {
);
}
}
function renderDidError(error) {
function renderDidError() {
if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
workInProgressRootExitStatus = RootErrored;
}
}
function queueConcurrentError(error) {
if (workInProgressRootConcurrentErrors === null) {
workInProgressRootConcurrentErrors = [error];
} else {
@@ -36811,7 +36837,7 @@ if (__DEV__) {
return root;
}
var ReactVersion = "19.0.0-www-classic-1334cd9a";
var ReactVersion = "19.0.0-www-classic-06a8599f";
function createPortal$1(
children,
@@ -18398,6 +18398,43 @@ if (__DEV__) {
return currentState.isDehydrated;
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
// Intentionally not using it yet to derisk the initial implementation, because
// the way we push/pop these values is a bit unusual. If there's a mistake, I'd
// rather the ids be wrong than crash the whole reconciler.
@@ -19466,6 +19503,11 @@ if (__DEV__) {
return false;
}
var HydrationMismatchException = new Error(
"Hydration Mismatch Exception: This is not a real error, and should not leak into " +
"userspace. If you're seeing this, it's likely a bug in React."
);
function throwOnHydrationMismatch(fiber) {
var diff = "";
@@ -19480,7 +19522,7 @@ if (__DEV__) {
}
}
throw new Error(
var error = new Error(
"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:\n" +
"\n" +
"- A server/client branch `if (typeof window !== 'undefined')`.\n" +
@@ -19494,6 +19536,8 @@ if (__DEV__) {
"https://react.dev/link/hydration-mismatch" +
diff
);
queueHydrationError(createCapturedValueAtFiber(error, fiber));
throw HydrationMismatchException;
}
function claimHydratableSingleton(fiber) {
@@ -19555,7 +19599,7 @@ if (__DEV__) {
warnNonHydratedInstance(fiber, nextInstance);
}
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -19579,7 +19623,7 @@ if (__DEV__) {
warnNonHydratedInstance(fiber, nextInstance);
}
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -19592,7 +19636,7 @@ if (__DEV__) {
if (!nextInstance || !tryHydrateSuspense(fiber, nextInstance)) {
warnNonHydratedInstance(fiber, nextInstance);
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -19620,7 +19664,7 @@ if (__DEV__) {
// rendering. We don't bother to check if we're in a concurrent root because
// useActionState is a new API, so backwards compat is not an issue.
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
return false;
}
@@ -19635,7 +19679,7 @@ if (__DEV__) {
);
if (!didHydrate && favorSafetyOverHydrationPerf) {
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -19702,7 +19746,7 @@ if (__DEV__) {
);
if (!didHydrate && favorSafetyOverHydrationPerf) {
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -19796,7 +19840,7 @@ if (__DEV__) {
if (nextInstance) {
warnIfUnhydratedTailNodes(fiber);
throwOnHydrationMismatch();
throwOnHydrationMismatch(fiber);
}
}
@@ -25701,7 +25745,9 @@ if (__DEV__) {
// matches this hook instance.
if (ssrFormState !== null) {
var isMatching = tryToClaimNextHydratableFormMarkerInstance();
var isMatching = tryToClaimNextHydratableFormMarkerInstance(
currentlyRenderingFiber$1
);
if (isMatching) {
initialState = ssrFormState[0];
@@ -29576,43 +29622,6 @@ if (__DEV__) {
return baseProps;
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
var ReactCurrentActQueue$2 = ReactSharedInternals.ReactCurrentActQueue; // Side-channel since I'm not sure we want to make this part of the public API
var componentName = null;
@@ -30103,13 +30112,65 @@ if (__DEV__) {
); // Even though the user may not be affected by this error, we should
// still log it so it can be fixed.
queueHydrationError(createCapturedValueAtFiber(value, sourceFiber));
if (value !== HydrationMismatchException) {
var _wrapperError = new Error(
"There was an error while hydrating but React was able to recover by " +
"instead client rendering from the nearest Suspense boundary.",
{
cause: value
}
);
queueHydrationError(
createCapturedValueAtFiber(_wrapperError, sourceFiber)
);
}
return false;
} else {
if (value !== HydrationMismatchException) {
var _wrapperError2 = new Error(
"There was an error while hydrating but React was able to recover by " +
"instead client rendering the entire root.",
{
cause: value
}
);
queueHydrationError(
createCapturedValueAtFiber(_wrapperError2, sourceFiber)
);
}
var _workInProgress = root.current.alternate; // Schedule an update at the root to log the error but this shouldn't
// actually happen because we should recover.
_workInProgress.flags |= ShouldCapture;
var lane = pickArbitraryLane(rootRenderLanes);
_workInProgress.lanes = mergeLanes(_workInProgress.lanes, lane);
var rootErrorInfo = createCapturedValueAtFiber(value, sourceFiber);
var update = createRootErrorUpdate(
_workInProgress.stateNode,
rootErrorInfo, // This should never actually get logged due to the recovery.
lane
);
enqueueCapturedUpdate(_workInProgress, update);
renderDidError();
return false;
}
}
value = createCapturedValueAtFiber(value, sourceFiber);
renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start
var wrapperError = new Error(
"There was an error during concurrent rendering but React was able to recover by " +
"instead synchronously rendering the entire root.",
{
cause: value
}
);
queueConcurrentError(
createCapturedValueAtFiber(wrapperError, sourceFiber)
);
renderDidError(); // We didn't find a boundary that could handle this type of exception. Start
// over and traverse parent path again, this time treating the exception
// as an error.
@@ -30119,34 +30180,30 @@ if (__DEV__) {
return true;
}
var errorInfo = createCapturedValueAtFiber(value, sourceFiber);
var workInProgress = returnFiber;
do {
switch (workInProgress.tag) {
case HostRoot: {
var _errorInfo = value;
workInProgress.flags |= ShouldCapture;
var lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
var update = createRootErrorUpdate(
var _lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane);
var _update = createRootErrorUpdate(
workInProgress.stateNode,
_errorInfo,
lane
errorInfo,
_lane
);
enqueueCapturedUpdate(workInProgress, update);
enqueueCapturedUpdate(workInProgress, _update);
return false;
}
case ClassComponent:
if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) {
// If we're hydrating and got here, it means that we didn't find a suspense
// boundary above so it's a root error. In this case we shouldn't let the
// error boundary capture it because it'll just try to hydrate the error state.
// Instead we let it bubble to the root and let the recover pass handle it.
break;
} // Capture and retry
var errorInfo = value;
// Capture and retry
var ctor = workInProgress.type;
var instance = workInProgress.stateNode;
@@ -30159,19 +30216,19 @@ if (__DEV__) {
) {
workInProgress.flags |= ShouldCapture;
var _lane = pickArbitraryLane(rootRenderLanes);
var _lane2 = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane2); // Schedule the error boundary to re-render using updated state
var _update = createClassErrorUpdate(_lane);
var _update2 = createClassErrorUpdate(_lane2);
initializeClassErrorUpdate(
_update,
_update2,
root,
workInProgress,
errorInfo
);
enqueueCapturedUpdate(workInProgress, _update);
enqueueCapturedUpdate(workInProgress, _update2);
return false;
}
@@ -31520,37 +31577,27 @@ if (__DEV__) {
if (workInProgress.flags & ForceClientRender) {
// Something errored during a previous attempt to hydrate the shell, so we
// forced a client render.
var recoverableError = createCapturedValueAtFiber(
new Error(
"There was an error while hydrating. Because the error happened outside " +
"of a Suspense boundary, the entire root will switch to " +
"client rendering."
),
workInProgress
);
// forced a client render. We should have a recoverable error already scheduled.
return mountHostRootWithoutHydrating(
current,
workInProgress,
nextChildren,
renderLanes,
recoverableError
renderLanes
);
} else if (nextChildren !== prevChildren) {
var _recoverableError = createCapturedValueAtFiber(
var recoverableError = createCapturedValueAtFiber(
new Error(
"This root received an early update, before anything was able " +
"hydrate. Switched the entire root to client rendering."
),
workInProgress
);
queueHydrationError(recoverableError);
return mountHostRootWithoutHydrating(
current,
workInProgress,
nextChildren,
renderLanes,
_recoverableError
renderLanes
);
} else {
// The outermost shell has not hydrated yet. Start hydrating.
@@ -31598,12 +31645,10 @@ if (__DEV__) {
current,
workInProgress,
nextChildren,
renderLanes,
recoverableError
renderLanes
) {
// Revert to client rendering.
resetHydrationState();
queueHydrationError(recoverableError);
workInProgress.flags |= ForceClientRender;
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
return workInProgress.child;
@@ -32461,20 +32506,12 @@ if (__DEV__) {
function retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
recoverableError
renderLanes
) {
// Falling back to client rendering. Because this has performance
// implications, it's considered a recoverable error, even though the user
// likely won't observe anything wrong with the UI.
//
// The error is passed in as an argument to enforce that every caller provide
// a custom message, or explicitly opt out (currently the only path that opts
// out is legacy mode; every concurrent path provides an error).
if (recoverableError !== null) {
queueHydrationError(recoverableError);
} // This will add the old fiber to the deletion list
// This will add the old fiber to the deletion list
reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
var nextProps = workInProgress.pendingProps;
@@ -32592,9 +32629,7 @@ if (__DEV__) {
message = _getSuspenseInstanceF.message;
stack = _getSuspenseInstanceF.stack;
componentStack = _getSuspenseInstanceF.componentStack;
}
var capturedValue = null; // TODO: Figure out a better signal than encoding a magic digest value.
} // TODO: Figure out a better signal than encoding a magic digest value.
{
var error;
@@ -32612,17 +32647,17 @@ if (__DEV__) {
error.stack = stack || "";
error.digest = digest;
capturedValue = createCapturedValueFromError(
var capturedValue = createCapturedValueFromError(
error,
componentStack === undefined ? null : componentStack
);
queueHydrationError(capturedValue);
}
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
capturedValue
renderLanes
);
}
@@ -32697,8 +32732,7 @@ if (__DEV__) {
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
null
renderLanes
);
} else if (isSuspenseInstancePending(suspenseInstance)) {
// This component is still pending more data from the server, so we can't hydrate its
@@ -32743,22 +32777,13 @@ if (__DEV__) {
// something either suspended or errored.
if (workInProgress.flags & ForceClientRender) {
// Something errored during hydration. Try again without hydrating.
// The error should've already been logged in throwException.
pushPrimaryTreeSuspenseHandler(workInProgress);
workInProgress.flags &= ~ForceClientRender;
var _capturedValue = createCapturedValueFromError(
new Error(
"There was an error while hydrating this Suspense boundary. " +
"Switched to client rendering."
),
null
);
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
_capturedValue
renderLanes
);
} else if (workInProgress.memoizedState !== null) {
// Something suspended and we should still be in dehydrated mode.
@@ -43137,11 +43162,12 @@ if (__DEV__) {
);
}
}
function renderDidError(error) {
function renderDidError() {
if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
workInProgressRootExitStatus = RootErrored;
}
}
function queueConcurrentError(error) {
if (workInProgressRootConcurrentErrors === null) {
workInProgressRootConcurrentErrors = [error];
} else {
@@ -46437,7 +46463,7 @@ if (__DEV__) {
return root;
}
var ReactVersion = "19.0.0-www-modern-8e64ec55";
var ReactVersion = "19.0.0-www-modern-2bc2ffbc";
function createPortal$1(
children,
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -2564,6 +2564,394 @@ if (__DEV__) {
var objectIs = typeof Object.is === "function" ? Object.is : is; // $FlowFixMe[method-unbinding]
var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher;
var prefix;
function describeBuiltInComponentFrame(name, ownerFn) {
{
if (prefix === undefined) {
// Extract the VM specific prefix used by each line.
try {
throw Error();
} catch (x) {
var match = x.stack.trim().match(/\n( *(at )?)/);
prefix = (match && match[1]) || "";
}
} // We use the prefix to ensure our stacks line up with native stack frames.
return "\n" + prefix + name;
}
}
function describeDebugInfoFrame(name, env) {
return describeBuiltInComponentFrame(
name + (env ? " (" + env + ")" : "")
);
}
var reentry = false;
var componentFrameCache;
{
var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map;
componentFrameCache = new PossiblyWeakMap$1();
}
/**
* Leverages native browser/VM stack frames to get proper details (e.g.
* filename, line + col number) for a single component in a component stack. We
* do this by:
* (1) throwing and catching an error in the function - this will be our
* control error.
* (2) calling the component which will eventually throw an error that we'll
* catch - this will be our sample error.
* (3) diffing the control and sample error stacks to find the stack frame
* which represents our component.
*/
function describeNativeComponentFrame(fn, construct) {
// If something asked for a stack inside a fake render, it should get ignored.
if (!fn || reentry) {
return "";
}
{
var frame = componentFrameCache.get(fn);
if (frame !== undefined) {
return frame;
}
}
reentry = true;
var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe[incompatible-type] It does accept undefined.
Error.prepareStackTrace = undefined;
var previousDispatcher;
{
previousDispatcher = ReactCurrentDispatcher$2.current; // Set the dispatcher in DEV because this might be call in the render function
// for warnings.
ReactCurrentDispatcher$2.current = null;
disableLogs();
}
/**
* Finding a common stack frame between sample and control errors can be
* tricky given the different types and levels of stack trace truncation from
* different JS VMs. So instead we'll attempt to control what that common
* frame should be through this object method:
* Having both the sample and control errors be in the function under the
* `DescribeNativeComponentFrameRoot` property, + setting the `name` and
* `displayName` properties of the function ensures that a stack
* frame exists that has the method name `DescribeNativeComponentFrameRoot` in
* it for both control and sample stacks.
*/
var RunInRootFrame = {
DetermineComponentFrameRoot: function () {
var control;
try {
// This should throw.
if (construct) {
// Something should be setting the props in the constructor.
var Fake = function () {
throw Error();
}; // $FlowFixMe[prop-missing]
Object.defineProperty(Fake.prototype, "props", {
set: function () {
// We use a throwing setter instead of frozen or non-writable props
// because that won't throw in a non-strict mode function.
throw Error();
}
});
if (typeof Reflect === "object" && Reflect.construct) {
// We construct a different control for this case to include any extra
// frames added by the construct call.
try {
Reflect.construct(Fake, []);
} catch (x) {
control = x;
}
Reflect.construct(fn, [], Fake);
} else {
try {
Fake.call();
} catch (x) {
control = x;
} // $FlowFixMe[prop-missing] found when upgrading Flow
fn.call(Fake.prototype);
}
} else {
try {
throw Error();
} catch (x) {
control = x;
} // TODO(luna): This will currently only throw if the function component
// tries to access React/ReactDOM/props. We should probably make this throw
// in simple components too
var maybePromise = fn(); // If the function component returns a promise, it's likely an async
// component, which we don't yet support. Attach a noop catch handler to
// silence the error.
// TODO: Implement component stacks for async client components?
if (maybePromise && typeof maybePromise.catch === "function") {
maybePromise.catch(function () {});
}
}
} catch (sample) {
// This is inlined manually because closure doesn't do it for us.
if (sample && control && typeof sample.stack === "string") {
return [sample.stack, control.stack];
}
}
return [null, null];
}
}; // $FlowFixMe[prop-missing]
RunInRootFrame.DetermineComponentFrameRoot.displayName =
"DetermineComponentFrameRoot";
var namePropDescriptor = Object.getOwnPropertyDescriptor(
RunInRootFrame.DetermineComponentFrameRoot,
"name"
); // Before ES6, the `name` property was not configurable.
if (namePropDescriptor && namePropDescriptor.configurable) {
// V8 utilizes a function's `name` property when generating a stack trace.
Object.defineProperty(
RunInRootFrame.DetermineComponentFrameRoot, // Configurable properties can be updated even if its writable descriptor
// is set to `false`.
// $FlowFixMe[cannot-write]
"name",
{
value: "DetermineComponentFrameRoot"
}
);
}
try {
var _RunInRootFrame$Deter =
RunInRootFrame.DetermineComponentFrameRoot(),
sampleStack = _RunInRootFrame$Deter[0],
controlStack = _RunInRootFrame$Deter[1];
if (sampleStack && controlStack) {
// This extracts the first frame from the sample that isn't also in the control.
// Skipping one frame that we assume is the frame that calls the two.
var sampleLines = sampleStack.split("\n");
var controlLines = controlStack.split("\n");
var s = 0;
var c = 0;
while (
s < sampleLines.length &&
!sampleLines[s].includes("DetermineComponentFrameRoot")
) {
s++;
}
while (
c < controlLines.length &&
!controlLines[c].includes("DetermineComponentFrameRoot")
) {
c++;
} // We couldn't find our intentionally injected common root frame, attempt
// to find another common root frame by search from the bottom of the
// control stack...
if (s === sampleLines.length || c === controlLines.length) {
s = sampleLines.length - 1;
c = controlLines.length - 1;
while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
// We expect at least one stack frame to be shared.
// Typically this will be the root most one. However, stack frames may be
// cut off due to maximum stack limits. In this case, one maybe cut off
// earlier than the other. We assume that the sample is longer or the same
// and there for cut off earlier. So we should find the root most frame in
// the sample somewhere in the control.
c--;
}
}
for (; s >= 1 && c >= 0; s--, c--) {
// Next we find the first one that isn't the same which should be the
// frame that called our sample function and the control.
if (sampleLines[s] !== controlLines[c]) {
// In V8, the first line is describing the message but other VMs don't.
// If we're about to return the first line, and the control is also on the same
// line, that's a pretty good indicator that our sample threw at same line as
// the control. I.e. before we entered the sample frame. So we ignore this result.
// This can happen if you passed a class to function component, or non-function.
if (s !== 1 || c !== 1) {
do {
s--;
c--; // We may still have similar intermediate frames from the construct call.
// The next one that isn't the same should be our match though.
if (c < 0 || sampleLines[s] !== controlLines[c]) {
// V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
var _frame =
"\n" + sampleLines[s].replace(" at new ", " at "); // If our component frame is labeled "<anonymous>"
// but we have a user-provided "displayName"
// splice it in to make the stack more readable.
if (fn.displayName && _frame.includes("<anonymous>")) {
_frame = _frame.replace("<anonymous>", fn.displayName);
}
if (true) {
if (typeof fn === "function") {
componentFrameCache.set(fn, _frame);
}
} // Return the line we found.
return _frame;
}
} while (s >= 1 && c >= 0);
}
break;
}
}
}
} finally {
reentry = false;
{
ReactCurrentDispatcher$2.current = previousDispatcher;
reenableLogs();
}
Error.prepareStackTrace = previousPrepareStackTrace;
} // Fallback to just using the name if we couldn't make it throw.
var name = fn ? fn.displayName || fn.name : "";
var syntheticFrame = name ? describeBuiltInComponentFrame(name) : "";
{
if (typeof fn === "function") {
componentFrameCache.set(fn, syntheticFrame);
}
}
return syntheticFrame;
}
function describeClassComponentFrame(ctor, ownerFn) {
{
return describeNativeComponentFrame(ctor, true);
}
}
function describeFunctionComponentFrame(fn, ownerFn) {
{
return describeNativeComponentFrame(fn, false);
}
}
function describeFiber(fiber) {
switch (fiber.tag) {
case HostHoistable:
case HostSingleton:
case HostComponent:
return describeBuiltInComponentFrame(fiber.type);
case LazyComponent:
return describeBuiltInComponentFrame("Lazy");
case SuspenseComponent:
return describeBuiltInComponentFrame("Suspense");
case SuspenseListComponent:
return describeBuiltInComponentFrame("SuspenseList");
case FunctionComponent:
case SimpleMemoComponent:
return describeFunctionComponentFrame(fiber.type);
case ForwardRef:
return describeFunctionComponentFrame(fiber.type.render);
case ClassComponent:
return describeClassComponentFrame(fiber.type);
default:
return "";
}
}
function getStackByFiberInDevAndProd(workInProgress) {
try {
var info = "";
var node = workInProgress;
do {
info += describeFiber(node);
if (true) {
// Add any Server Component stack frames in reverse order.
var debugInfo = node._debugInfo;
if (debugInfo) {
for (var i = debugInfo.length - 1; i >= 0; i--) {
var entry = debugInfo[i];
if (typeof entry.name === "string") {
info += describeDebugInfoFrame(entry.name, entry.env);
}
}
}
} // $FlowFixMe[incompatible-type] we bail out when we get a null
node = node.return;
} while (node);
return info;
} catch (x) {
return "\nError generating stack: " + x.message + "\n" + x.stack;
}
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
var contextStackCursor = createCursor(null);
var contextFiberStackCursor = createCursor(null);
var rootInstanceStackCursor = createCursor(null); // Represents the nearest host transition provider (in React DOM, a <form />)
@@ -4760,357 +5148,6 @@ if (__DEV__) {
return true;
}
var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher;
var prefix;
function describeBuiltInComponentFrame(name, ownerFn) {
{
if (prefix === undefined) {
// Extract the VM specific prefix used by each line.
try {
throw Error();
} catch (x) {
var match = x.stack.trim().match(/\n( *(at )?)/);
prefix = (match && match[1]) || "";
}
} // We use the prefix to ensure our stacks line up with native stack frames.
return "\n" + prefix + name;
}
}
function describeDebugInfoFrame(name, env) {
return describeBuiltInComponentFrame(
name + (env ? " (" + env + ")" : "")
);
}
var reentry = false;
var componentFrameCache;
{
var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map;
componentFrameCache = new PossiblyWeakMap$1();
}
/**
* Leverages native browser/VM stack frames to get proper details (e.g.
* filename, line + col number) for a single component in a component stack. We
* do this by:
* (1) throwing and catching an error in the function - this will be our
* control error.
* (2) calling the component which will eventually throw an error that we'll
* catch - this will be our sample error.
* (3) diffing the control and sample error stacks to find the stack frame
* which represents our component.
*/
function describeNativeComponentFrame(fn, construct) {
// If something asked for a stack inside a fake render, it should get ignored.
if (!fn || reentry) {
return "";
}
{
var frame = componentFrameCache.get(fn);
if (frame !== undefined) {
return frame;
}
}
reentry = true;
var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe[incompatible-type] It does accept undefined.
Error.prepareStackTrace = undefined;
var previousDispatcher;
{
previousDispatcher = ReactCurrentDispatcher$2.current; // Set the dispatcher in DEV because this might be call in the render function
// for warnings.
ReactCurrentDispatcher$2.current = null;
disableLogs();
}
/**
* Finding a common stack frame between sample and control errors can be
* tricky given the different types and levels of stack trace truncation from
* different JS VMs. So instead we'll attempt to control what that common
* frame should be through this object method:
* Having both the sample and control errors be in the function under the
* `DescribeNativeComponentFrameRoot` property, + setting the `name` and
* `displayName` properties of the function ensures that a stack
* frame exists that has the method name `DescribeNativeComponentFrameRoot` in
* it for both control and sample stacks.
*/
var RunInRootFrame = {
DetermineComponentFrameRoot: function () {
var control;
try {
// This should throw.
if (construct) {
// Something should be setting the props in the constructor.
var Fake = function () {
throw Error();
}; // $FlowFixMe[prop-missing]
Object.defineProperty(Fake.prototype, "props", {
set: function () {
// We use a throwing setter instead of frozen or non-writable props
// because that won't throw in a non-strict mode function.
throw Error();
}
});
if (typeof Reflect === "object" && Reflect.construct) {
// We construct a different control for this case to include any extra
// frames added by the construct call.
try {
Reflect.construct(Fake, []);
} catch (x) {
control = x;
}
Reflect.construct(fn, [], Fake);
} else {
try {
Fake.call();
} catch (x) {
control = x;
} // $FlowFixMe[prop-missing] found when upgrading Flow
fn.call(Fake.prototype);
}
} else {
try {
throw Error();
} catch (x) {
control = x;
} // TODO(luna): This will currently only throw if the function component
// tries to access React/ReactDOM/props. We should probably make this throw
// in simple components too
var maybePromise = fn(); // If the function component returns a promise, it's likely an async
// component, which we don't yet support. Attach a noop catch handler to
// silence the error.
// TODO: Implement component stacks for async client components?
if (maybePromise && typeof maybePromise.catch === "function") {
maybePromise.catch(function () {});
}
}
} catch (sample) {
// This is inlined manually because closure doesn't do it for us.
if (sample && control && typeof sample.stack === "string") {
return [sample.stack, control.stack];
}
}
return [null, null];
}
}; // $FlowFixMe[prop-missing]
RunInRootFrame.DetermineComponentFrameRoot.displayName =
"DetermineComponentFrameRoot";
var namePropDescriptor = Object.getOwnPropertyDescriptor(
RunInRootFrame.DetermineComponentFrameRoot,
"name"
); // Before ES6, the `name` property was not configurable.
if (namePropDescriptor && namePropDescriptor.configurable) {
// V8 utilizes a function's `name` property when generating a stack trace.
Object.defineProperty(
RunInRootFrame.DetermineComponentFrameRoot, // Configurable properties can be updated even if its writable descriptor
// is set to `false`.
// $FlowFixMe[cannot-write]
"name",
{
value: "DetermineComponentFrameRoot"
}
);
}
try {
var _RunInRootFrame$Deter =
RunInRootFrame.DetermineComponentFrameRoot(),
sampleStack = _RunInRootFrame$Deter[0],
controlStack = _RunInRootFrame$Deter[1];
if (sampleStack && controlStack) {
// This extracts the first frame from the sample that isn't also in the control.
// Skipping one frame that we assume is the frame that calls the two.
var sampleLines = sampleStack.split("\n");
var controlLines = controlStack.split("\n");
var s = 0;
var c = 0;
while (
s < sampleLines.length &&
!sampleLines[s].includes("DetermineComponentFrameRoot")
) {
s++;
}
while (
c < controlLines.length &&
!controlLines[c].includes("DetermineComponentFrameRoot")
) {
c++;
} // We couldn't find our intentionally injected common root frame, attempt
// to find another common root frame by search from the bottom of the
// control stack...
if (s === sampleLines.length || c === controlLines.length) {
s = sampleLines.length - 1;
c = controlLines.length - 1;
while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
// We expect at least one stack frame to be shared.
// Typically this will be the root most one. However, stack frames may be
// cut off due to maximum stack limits. In this case, one maybe cut off
// earlier than the other. We assume that the sample is longer or the same
// and there for cut off earlier. So we should find the root most frame in
// the sample somewhere in the control.
c--;
}
}
for (; s >= 1 && c >= 0; s--, c--) {
// Next we find the first one that isn't the same which should be the
// frame that called our sample function and the control.
if (sampleLines[s] !== controlLines[c]) {
// In V8, the first line is describing the message but other VMs don't.
// If we're about to return the first line, and the control is also on the same
// line, that's a pretty good indicator that our sample threw at same line as
// the control. I.e. before we entered the sample frame. So we ignore this result.
// This can happen if you passed a class to function component, or non-function.
if (s !== 1 || c !== 1) {
do {
s--;
c--; // We may still have similar intermediate frames from the construct call.
// The next one that isn't the same should be our match though.
if (c < 0 || sampleLines[s] !== controlLines[c]) {
// V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
var _frame =
"\n" + sampleLines[s].replace(" at new ", " at "); // If our component frame is labeled "<anonymous>"
// but we have a user-provided "displayName"
// splice it in to make the stack more readable.
if (fn.displayName && _frame.includes("<anonymous>")) {
_frame = _frame.replace("<anonymous>", fn.displayName);
}
if (true) {
if (typeof fn === "function") {
componentFrameCache.set(fn, _frame);
}
} // Return the line we found.
return _frame;
}
} while (s >= 1 && c >= 0);
}
break;
}
}
}
} finally {
reentry = false;
{
ReactCurrentDispatcher$2.current = previousDispatcher;
reenableLogs();
}
Error.prepareStackTrace = previousPrepareStackTrace;
} // Fallback to just using the name if we couldn't make it throw.
var name = fn ? fn.displayName || fn.name : "";
var syntheticFrame = name ? describeBuiltInComponentFrame(name) : "";
{
if (typeof fn === "function") {
componentFrameCache.set(fn, syntheticFrame);
}
}
return syntheticFrame;
}
function describeClassComponentFrame(ctor, ownerFn) {
{
return describeNativeComponentFrame(ctor, true);
}
}
function describeFunctionComponentFrame(fn, ownerFn) {
{
return describeNativeComponentFrame(fn, false);
}
}
function describeFiber(fiber) {
switch (fiber.tag) {
case HostHoistable:
case HostSingleton:
case HostComponent:
return describeBuiltInComponentFrame(fiber.type);
case LazyComponent:
return describeBuiltInComponentFrame("Lazy");
case SuspenseComponent:
return describeBuiltInComponentFrame("Suspense");
case SuspenseListComponent:
return describeBuiltInComponentFrame("SuspenseList");
case FunctionComponent:
case SimpleMemoComponent:
return describeFunctionComponentFrame(fiber.type);
case ForwardRef:
return describeFunctionComponentFrame(fiber.type.render);
case ClassComponent:
return describeClassComponentFrame(fiber.type);
default:
return "";
}
}
function getStackByFiberInDevAndProd(workInProgress) {
try {
var info = "";
var node = workInProgress;
do {
info += describeFiber(node);
if (true) {
// Add any Server Component stack frames in reverse order.
var debugInfo = node._debugInfo;
if (debugInfo) {
for (var i = debugInfo.length - 1; i >= 0; i--) {
var entry = debugInfo[i];
if (typeof entry.name === "string") {
info += describeDebugInfoFrame(entry.name, entry.env);
}
}
}
} // $FlowFixMe[incompatible-type] we bail out when we get a null
node = node.return;
} while (node);
return info;
} catch (x) {
return "\nError generating stack: " + x.message + "\n" + x.stack;
}
}
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
var current = null;
var isRendering = false;
@@ -13126,43 +13163,6 @@ if (__DEV__) {
return baseProps;
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
var reportGlobalError =
typeof reportError === "function" // In modern browsers, reportError will dispatch an error event,
? // emulating an uncaught JavaScript error.
@@ -13725,8 +13725,17 @@ if (__DEV__) {
}
} // This is a regular error, not a Suspense wakeable.
value = createCapturedValueAtFiber(value, sourceFiber);
renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start
var wrapperError = new Error(
"There was an error during concurrent rendering but React was able to recover by " +
"instead synchronously rendering the entire root.",
{
cause: value
}
);
queueConcurrentError(
createCapturedValueAtFiber(wrapperError, sourceFiber)
);
renderDidError(); // We didn't find a boundary that could handle this type of exception. Start
// over and traverse parent path again, this time treating the exception
// as an error.
@@ -13736,26 +13745,30 @@ if (__DEV__) {
return true;
}
var errorInfo = createCapturedValueAtFiber(value, sourceFiber);
var workInProgress = returnFiber;
do {
switch (workInProgress.tag) {
case HostRoot: {
var _errorInfo = value;
workInProgress.flags |= ShouldCapture;
var lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
var update = createRootErrorUpdate(
var _lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane);
var _update = createRootErrorUpdate(
workInProgress.stateNode,
_errorInfo,
lane
errorInfo,
_lane
);
enqueueCapturedUpdate(workInProgress, update);
enqueueCapturedUpdate(workInProgress, _update);
return false;
}
case ClassComponent:
var errorInfo = value;
// Capture and retry
var ctor = workInProgress.type;
var instance = workInProgress.stateNode;
@@ -13768,19 +13781,19 @@ if (__DEV__) {
) {
workInProgress.flags |= ShouldCapture;
var _lane = pickArbitraryLane(rootRenderLanes);
var _lane2 = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane2); // Schedule the error boundary to re-render using updated state
var _update = createClassErrorUpdate(_lane);
var _update2 = createClassErrorUpdate(_lane2);
initializeClassErrorUpdate(
_update,
_update2,
root,
workInProgress,
errorInfo
);
enqueueCapturedUpdate(workInProgress, _update);
enqueueCapturedUpdate(workInProgress, _update2);
return false;
}
@@ -15578,20 +15591,12 @@ if (__DEV__) {
function retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
recoverableError
renderLanes
) {
// Falling back to client rendering. Because this has performance
// implications, it's considered a recoverable error, even though the user
// likely won't observe anything wrong with the UI.
//
// The error is passed in as an argument to enforce that every caller provide
// a custom message, or explicitly opt out (currently the only path that opts
// out is legacy mode; every concurrent path provides an error).
if (recoverableError !== null) {
queueHydrationError(recoverableError);
} // This will add the old fiber to the deletion list
// This will add the old fiber to the deletion list
reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
var nextProps = workInProgress.pendingProps;
@@ -15677,9 +15682,7 @@ if (__DEV__) {
message = _getSuspenseInstanceF.message;
stack = _getSuspenseInstanceF.stack;
componentStack = _getSuspenseInstanceF.componentStack;
}
var capturedValue = null; // TODO: Figure out a better signal than encoding a magic digest value.
} // TODO: Figure out a better signal than encoding a magic digest value.
{
var error;
@@ -15697,17 +15700,17 @@ if (__DEV__) {
error.stack = stack || "";
error.digest = digest;
capturedValue = createCapturedValueFromError(
var capturedValue = createCapturedValueFromError(
error,
componentStack === undefined ? null : componentStack
);
queueHydrationError(capturedValue);
}
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
capturedValue
renderLanes
);
}
// any context has changed, we need to treat is as if the input might have changed.
@@ -15767,8 +15770,7 @@ if (__DEV__) {
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
null
renderLanes
);
} else if (isSuspenseInstancePending()) {
// This component is still pending more data from the server, so we can't hydrate its
@@ -15807,22 +15809,13 @@ if (__DEV__) {
// something either suspended or errored.
if (workInProgress.flags & ForceClientRender) {
// Something errored during hydration. Try again without hydrating.
// The error should've already been logged in throwException.
pushPrimaryTreeSuspenseHandler(workInProgress);
workInProgress.flags &= ~ForceClientRender;
var _capturedValue = createCapturedValueFromError(
new Error(
"There was an error while hydrating this Suspense boundary. " +
"Switched to client rendering."
),
null
);
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
_capturedValue
renderLanes
);
} else if (workInProgress.memoizedState !== null) {
// Something suspended and we should still be in dehydrated mode.
@@ -23897,11 +23890,12 @@ if (__DEV__) {
);
}
}
function renderDidError(error) {
function renderDidError() {
if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
workInProgressRootExitStatus = RootErrored;
}
}
function queueConcurrentError(error) {
if (workInProgressRootConcurrentErrors === null) {
workInProgressRootConcurrentErrors = [error];
} else {
@@ -26833,7 +26827,7 @@ if (__DEV__) {
return root;
}
var ReactVersion = "19.0.0-www-classic-ea7c02d5";
var ReactVersion = "19.0.0-www-classic-272ef63e";
// Might add PROFILE later.
@@ -2564,6 +2564,394 @@ if (__DEV__) {
var objectIs = typeof Object.is === "function" ? Object.is : is; // $FlowFixMe[method-unbinding]
var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher;
var prefix;
function describeBuiltInComponentFrame(name, ownerFn) {
{
if (prefix === undefined) {
// Extract the VM specific prefix used by each line.
try {
throw Error();
} catch (x) {
var match = x.stack.trim().match(/\n( *(at )?)/);
prefix = (match && match[1]) || "";
}
} // We use the prefix to ensure our stacks line up with native stack frames.
return "\n" + prefix + name;
}
}
function describeDebugInfoFrame(name, env) {
return describeBuiltInComponentFrame(
name + (env ? " (" + env + ")" : "")
);
}
var reentry = false;
var componentFrameCache;
{
var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map;
componentFrameCache = new PossiblyWeakMap$1();
}
/**
* Leverages native browser/VM stack frames to get proper details (e.g.
* filename, line + col number) for a single component in a component stack. We
* do this by:
* (1) throwing and catching an error in the function - this will be our
* control error.
* (2) calling the component which will eventually throw an error that we'll
* catch - this will be our sample error.
* (3) diffing the control and sample error stacks to find the stack frame
* which represents our component.
*/
function describeNativeComponentFrame(fn, construct) {
// If something asked for a stack inside a fake render, it should get ignored.
if (!fn || reentry) {
return "";
}
{
var frame = componentFrameCache.get(fn);
if (frame !== undefined) {
return frame;
}
}
reentry = true;
var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe[incompatible-type] It does accept undefined.
Error.prepareStackTrace = undefined;
var previousDispatcher;
{
previousDispatcher = ReactCurrentDispatcher$2.current; // Set the dispatcher in DEV because this might be call in the render function
// for warnings.
ReactCurrentDispatcher$2.current = null;
disableLogs();
}
/**
* Finding a common stack frame between sample and control errors can be
* tricky given the different types and levels of stack trace truncation from
* different JS VMs. So instead we'll attempt to control what that common
* frame should be through this object method:
* Having both the sample and control errors be in the function under the
* `DescribeNativeComponentFrameRoot` property, + setting the `name` and
* `displayName` properties of the function ensures that a stack
* frame exists that has the method name `DescribeNativeComponentFrameRoot` in
* it for both control and sample stacks.
*/
var RunInRootFrame = {
DetermineComponentFrameRoot: function () {
var control;
try {
// This should throw.
if (construct) {
// Something should be setting the props in the constructor.
var Fake = function () {
throw Error();
}; // $FlowFixMe[prop-missing]
Object.defineProperty(Fake.prototype, "props", {
set: function () {
// We use a throwing setter instead of frozen or non-writable props
// because that won't throw in a non-strict mode function.
throw Error();
}
});
if (typeof Reflect === "object" && Reflect.construct) {
// We construct a different control for this case to include any extra
// frames added by the construct call.
try {
Reflect.construct(Fake, []);
} catch (x) {
control = x;
}
Reflect.construct(fn, [], Fake);
} else {
try {
Fake.call();
} catch (x) {
control = x;
} // $FlowFixMe[prop-missing] found when upgrading Flow
fn.call(Fake.prototype);
}
} else {
try {
throw Error();
} catch (x) {
control = x;
} // TODO(luna): This will currently only throw if the function component
// tries to access React/ReactDOM/props. We should probably make this throw
// in simple components too
var maybePromise = fn(); // If the function component returns a promise, it's likely an async
// component, which we don't yet support. Attach a noop catch handler to
// silence the error.
// TODO: Implement component stacks for async client components?
if (maybePromise && typeof maybePromise.catch === "function") {
maybePromise.catch(function () {});
}
}
} catch (sample) {
// This is inlined manually because closure doesn't do it for us.
if (sample && control && typeof sample.stack === "string") {
return [sample.stack, control.stack];
}
}
return [null, null];
}
}; // $FlowFixMe[prop-missing]
RunInRootFrame.DetermineComponentFrameRoot.displayName =
"DetermineComponentFrameRoot";
var namePropDescriptor = Object.getOwnPropertyDescriptor(
RunInRootFrame.DetermineComponentFrameRoot,
"name"
); // Before ES6, the `name` property was not configurable.
if (namePropDescriptor && namePropDescriptor.configurable) {
// V8 utilizes a function's `name` property when generating a stack trace.
Object.defineProperty(
RunInRootFrame.DetermineComponentFrameRoot, // Configurable properties can be updated even if its writable descriptor
// is set to `false`.
// $FlowFixMe[cannot-write]
"name",
{
value: "DetermineComponentFrameRoot"
}
);
}
try {
var _RunInRootFrame$Deter =
RunInRootFrame.DetermineComponentFrameRoot(),
sampleStack = _RunInRootFrame$Deter[0],
controlStack = _RunInRootFrame$Deter[1];
if (sampleStack && controlStack) {
// This extracts the first frame from the sample that isn't also in the control.
// Skipping one frame that we assume is the frame that calls the two.
var sampleLines = sampleStack.split("\n");
var controlLines = controlStack.split("\n");
var s = 0;
var c = 0;
while (
s < sampleLines.length &&
!sampleLines[s].includes("DetermineComponentFrameRoot")
) {
s++;
}
while (
c < controlLines.length &&
!controlLines[c].includes("DetermineComponentFrameRoot")
) {
c++;
} // We couldn't find our intentionally injected common root frame, attempt
// to find another common root frame by search from the bottom of the
// control stack...
if (s === sampleLines.length || c === controlLines.length) {
s = sampleLines.length - 1;
c = controlLines.length - 1;
while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
// We expect at least one stack frame to be shared.
// Typically this will be the root most one. However, stack frames may be
// cut off due to maximum stack limits. In this case, one maybe cut off
// earlier than the other. We assume that the sample is longer or the same
// and there for cut off earlier. So we should find the root most frame in
// the sample somewhere in the control.
c--;
}
}
for (; s >= 1 && c >= 0; s--, c--) {
// Next we find the first one that isn't the same which should be the
// frame that called our sample function and the control.
if (sampleLines[s] !== controlLines[c]) {
// In V8, the first line is describing the message but other VMs don't.
// If we're about to return the first line, and the control is also on the same
// line, that's a pretty good indicator that our sample threw at same line as
// the control. I.e. before we entered the sample frame. So we ignore this result.
// This can happen if you passed a class to function component, or non-function.
if (s !== 1 || c !== 1) {
do {
s--;
c--; // We may still have similar intermediate frames from the construct call.
// The next one that isn't the same should be our match though.
if (c < 0 || sampleLines[s] !== controlLines[c]) {
// V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
var _frame =
"\n" + sampleLines[s].replace(" at new ", " at "); // If our component frame is labeled "<anonymous>"
// but we have a user-provided "displayName"
// splice it in to make the stack more readable.
if (fn.displayName && _frame.includes("<anonymous>")) {
_frame = _frame.replace("<anonymous>", fn.displayName);
}
if (true) {
if (typeof fn === "function") {
componentFrameCache.set(fn, _frame);
}
} // Return the line we found.
return _frame;
}
} while (s >= 1 && c >= 0);
}
break;
}
}
}
} finally {
reentry = false;
{
ReactCurrentDispatcher$2.current = previousDispatcher;
reenableLogs();
}
Error.prepareStackTrace = previousPrepareStackTrace;
} // Fallback to just using the name if we couldn't make it throw.
var name = fn ? fn.displayName || fn.name : "";
var syntheticFrame = name ? describeBuiltInComponentFrame(name) : "";
{
if (typeof fn === "function") {
componentFrameCache.set(fn, syntheticFrame);
}
}
return syntheticFrame;
}
function describeClassComponentFrame(ctor, ownerFn) {
{
return describeNativeComponentFrame(ctor, true);
}
}
function describeFunctionComponentFrame(fn, ownerFn) {
{
return describeNativeComponentFrame(fn, false);
}
}
function describeFiber(fiber) {
switch (fiber.tag) {
case HostHoistable:
case HostSingleton:
case HostComponent:
return describeBuiltInComponentFrame(fiber.type);
case LazyComponent:
return describeBuiltInComponentFrame("Lazy");
case SuspenseComponent:
return describeBuiltInComponentFrame("Suspense");
case SuspenseListComponent:
return describeBuiltInComponentFrame("SuspenseList");
case FunctionComponent:
case SimpleMemoComponent:
return describeFunctionComponentFrame(fiber.type);
case ForwardRef:
return describeFunctionComponentFrame(fiber.type.render);
case ClassComponent:
return describeClassComponentFrame(fiber.type);
default:
return "";
}
}
function getStackByFiberInDevAndProd(workInProgress) {
try {
var info = "";
var node = workInProgress;
do {
info += describeFiber(node);
if (true) {
// Add any Server Component stack frames in reverse order.
var debugInfo = node._debugInfo;
if (debugInfo) {
for (var i = debugInfo.length - 1; i >= 0; i--) {
var entry = debugInfo[i];
if (typeof entry.name === "string") {
info += describeDebugInfoFrame(entry.name, entry.env);
}
}
}
} // $FlowFixMe[incompatible-type] we bail out when we get a null
node = node.return;
} while (node);
return info;
} catch (x) {
return "\nError generating stack: " + x.message + "\n" + x.stack;
}
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
var contextStackCursor = createCursor(null);
var contextFiberStackCursor = createCursor(null);
var rootInstanceStackCursor = createCursor(null); // Represents the nearest host transition provider (in React DOM, a <form />)
@@ -4760,357 +5148,6 @@ if (__DEV__) {
return true;
}
var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher;
var prefix;
function describeBuiltInComponentFrame(name, ownerFn) {
{
if (prefix === undefined) {
// Extract the VM specific prefix used by each line.
try {
throw Error();
} catch (x) {
var match = x.stack.trim().match(/\n( *(at )?)/);
prefix = (match && match[1]) || "";
}
} // We use the prefix to ensure our stacks line up with native stack frames.
return "\n" + prefix + name;
}
}
function describeDebugInfoFrame(name, env) {
return describeBuiltInComponentFrame(
name + (env ? " (" + env + ")" : "")
);
}
var reentry = false;
var componentFrameCache;
{
var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map;
componentFrameCache = new PossiblyWeakMap$1();
}
/**
* Leverages native browser/VM stack frames to get proper details (e.g.
* filename, line + col number) for a single component in a component stack. We
* do this by:
* (1) throwing and catching an error in the function - this will be our
* control error.
* (2) calling the component which will eventually throw an error that we'll
* catch - this will be our sample error.
* (3) diffing the control and sample error stacks to find the stack frame
* which represents our component.
*/
function describeNativeComponentFrame(fn, construct) {
// If something asked for a stack inside a fake render, it should get ignored.
if (!fn || reentry) {
return "";
}
{
var frame = componentFrameCache.get(fn);
if (frame !== undefined) {
return frame;
}
}
reentry = true;
var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe[incompatible-type] It does accept undefined.
Error.prepareStackTrace = undefined;
var previousDispatcher;
{
previousDispatcher = ReactCurrentDispatcher$2.current; // Set the dispatcher in DEV because this might be call in the render function
// for warnings.
ReactCurrentDispatcher$2.current = null;
disableLogs();
}
/**
* Finding a common stack frame between sample and control errors can be
* tricky given the different types and levels of stack trace truncation from
* different JS VMs. So instead we'll attempt to control what that common
* frame should be through this object method:
* Having both the sample and control errors be in the function under the
* `DescribeNativeComponentFrameRoot` property, + setting the `name` and
* `displayName` properties of the function ensures that a stack
* frame exists that has the method name `DescribeNativeComponentFrameRoot` in
* it for both control and sample stacks.
*/
var RunInRootFrame = {
DetermineComponentFrameRoot: function () {
var control;
try {
// This should throw.
if (construct) {
// Something should be setting the props in the constructor.
var Fake = function () {
throw Error();
}; // $FlowFixMe[prop-missing]
Object.defineProperty(Fake.prototype, "props", {
set: function () {
// We use a throwing setter instead of frozen or non-writable props
// because that won't throw in a non-strict mode function.
throw Error();
}
});
if (typeof Reflect === "object" && Reflect.construct) {
// We construct a different control for this case to include any extra
// frames added by the construct call.
try {
Reflect.construct(Fake, []);
} catch (x) {
control = x;
}
Reflect.construct(fn, [], Fake);
} else {
try {
Fake.call();
} catch (x) {
control = x;
} // $FlowFixMe[prop-missing] found when upgrading Flow
fn.call(Fake.prototype);
}
} else {
try {
throw Error();
} catch (x) {
control = x;
} // TODO(luna): This will currently only throw if the function component
// tries to access React/ReactDOM/props. We should probably make this throw
// in simple components too
var maybePromise = fn(); // If the function component returns a promise, it's likely an async
// component, which we don't yet support. Attach a noop catch handler to
// silence the error.
// TODO: Implement component stacks for async client components?
if (maybePromise && typeof maybePromise.catch === "function") {
maybePromise.catch(function () {});
}
}
} catch (sample) {
// This is inlined manually because closure doesn't do it for us.
if (sample && control && typeof sample.stack === "string") {
return [sample.stack, control.stack];
}
}
return [null, null];
}
}; // $FlowFixMe[prop-missing]
RunInRootFrame.DetermineComponentFrameRoot.displayName =
"DetermineComponentFrameRoot";
var namePropDescriptor = Object.getOwnPropertyDescriptor(
RunInRootFrame.DetermineComponentFrameRoot,
"name"
); // Before ES6, the `name` property was not configurable.
if (namePropDescriptor && namePropDescriptor.configurable) {
// V8 utilizes a function's `name` property when generating a stack trace.
Object.defineProperty(
RunInRootFrame.DetermineComponentFrameRoot, // Configurable properties can be updated even if its writable descriptor
// is set to `false`.
// $FlowFixMe[cannot-write]
"name",
{
value: "DetermineComponentFrameRoot"
}
);
}
try {
var _RunInRootFrame$Deter =
RunInRootFrame.DetermineComponentFrameRoot(),
sampleStack = _RunInRootFrame$Deter[0],
controlStack = _RunInRootFrame$Deter[1];
if (sampleStack && controlStack) {
// This extracts the first frame from the sample that isn't also in the control.
// Skipping one frame that we assume is the frame that calls the two.
var sampleLines = sampleStack.split("\n");
var controlLines = controlStack.split("\n");
var s = 0;
var c = 0;
while (
s < sampleLines.length &&
!sampleLines[s].includes("DetermineComponentFrameRoot")
) {
s++;
}
while (
c < controlLines.length &&
!controlLines[c].includes("DetermineComponentFrameRoot")
) {
c++;
} // We couldn't find our intentionally injected common root frame, attempt
// to find another common root frame by search from the bottom of the
// control stack...
if (s === sampleLines.length || c === controlLines.length) {
s = sampleLines.length - 1;
c = controlLines.length - 1;
while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
// We expect at least one stack frame to be shared.
// Typically this will be the root most one. However, stack frames may be
// cut off due to maximum stack limits. In this case, one maybe cut off
// earlier than the other. We assume that the sample is longer or the same
// and there for cut off earlier. So we should find the root most frame in
// the sample somewhere in the control.
c--;
}
}
for (; s >= 1 && c >= 0; s--, c--) {
// Next we find the first one that isn't the same which should be the
// frame that called our sample function and the control.
if (sampleLines[s] !== controlLines[c]) {
// In V8, the first line is describing the message but other VMs don't.
// If we're about to return the first line, and the control is also on the same
// line, that's a pretty good indicator that our sample threw at same line as
// the control. I.e. before we entered the sample frame. So we ignore this result.
// This can happen if you passed a class to function component, or non-function.
if (s !== 1 || c !== 1) {
do {
s--;
c--; // We may still have similar intermediate frames from the construct call.
// The next one that isn't the same should be our match though.
if (c < 0 || sampleLines[s] !== controlLines[c]) {
// V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
var _frame =
"\n" + sampleLines[s].replace(" at new ", " at "); // If our component frame is labeled "<anonymous>"
// but we have a user-provided "displayName"
// splice it in to make the stack more readable.
if (fn.displayName && _frame.includes("<anonymous>")) {
_frame = _frame.replace("<anonymous>", fn.displayName);
}
if (true) {
if (typeof fn === "function") {
componentFrameCache.set(fn, _frame);
}
} // Return the line we found.
return _frame;
}
} while (s >= 1 && c >= 0);
}
break;
}
}
}
} finally {
reentry = false;
{
ReactCurrentDispatcher$2.current = previousDispatcher;
reenableLogs();
}
Error.prepareStackTrace = previousPrepareStackTrace;
} // Fallback to just using the name if we couldn't make it throw.
var name = fn ? fn.displayName || fn.name : "";
var syntheticFrame = name ? describeBuiltInComponentFrame(name) : "";
{
if (typeof fn === "function") {
componentFrameCache.set(fn, syntheticFrame);
}
}
return syntheticFrame;
}
function describeClassComponentFrame(ctor, ownerFn) {
{
return describeNativeComponentFrame(ctor, true);
}
}
function describeFunctionComponentFrame(fn, ownerFn) {
{
return describeNativeComponentFrame(fn, false);
}
}
function describeFiber(fiber) {
switch (fiber.tag) {
case HostHoistable:
case HostSingleton:
case HostComponent:
return describeBuiltInComponentFrame(fiber.type);
case LazyComponent:
return describeBuiltInComponentFrame("Lazy");
case SuspenseComponent:
return describeBuiltInComponentFrame("Suspense");
case SuspenseListComponent:
return describeBuiltInComponentFrame("SuspenseList");
case FunctionComponent:
case SimpleMemoComponent:
return describeFunctionComponentFrame(fiber.type);
case ForwardRef:
return describeFunctionComponentFrame(fiber.type.render);
case ClassComponent:
return describeClassComponentFrame(fiber.type);
default:
return "";
}
}
function getStackByFiberInDevAndProd(workInProgress) {
try {
var info = "";
var node = workInProgress;
do {
info += describeFiber(node);
if (true) {
// Add any Server Component stack frames in reverse order.
var debugInfo = node._debugInfo;
if (debugInfo) {
for (var i = debugInfo.length - 1; i >= 0; i--) {
var entry = debugInfo[i];
if (typeof entry.name === "string") {
info += describeDebugInfoFrame(entry.name, entry.env);
}
}
}
} // $FlowFixMe[incompatible-type] we bail out when we get a null
node = node.return;
} while (node);
return info;
} catch (x) {
return "\nError generating stack: " + x.message + "\n" + x.stack;
}
}
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
var current = null;
var isRendering = false;
@@ -13126,43 +13163,6 @@ if (__DEV__) {
return baseProps;
}
var CapturedStacks = new WeakMap();
function createCapturedValueAtFiber(value, source) {
// If the value is an error, call this function immediately after it is thrown
// so the stack is accurate.
var stack;
if (typeof value === "object" && value !== null) {
var capturedStack = CapturedStacks.get(value);
if (typeof capturedStack === "string") {
stack = capturedStack;
} else {
stack = getStackByFiberInDevAndProd(source);
CapturedStacks.set(value, stack);
}
} else {
stack = getStackByFiberInDevAndProd(source);
}
return {
value: value,
source: source,
stack: stack
};
}
function createCapturedValueFromError(value, stack) {
if (typeof stack === "string") {
CapturedStacks.set(value, stack);
}
return {
value: value,
source: null,
stack: stack
};
}
var reportGlobalError =
typeof reportError === "function" // In modern browsers, reportError will dispatch an error event,
? // emulating an uncaught JavaScript error.
@@ -13725,8 +13725,17 @@ if (__DEV__) {
}
} // This is a regular error, not a Suspense wakeable.
value = createCapturedValueAtFiber(value, sourceFiber);
renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start
var wrapperError = new Error(
"There was an error during concurrent rendering but React was able to recover by " +
"instead synchronously rendering the entire root.",
{
cause: value
}
);
queueConcurrentError(
createCapturedValueAtFiber(wrapperError, sourceFiber)
);
renderDidError(); // We didn't find a boundary that could handle this type of exception. Start
// over and traverse parent path again, this time treating the exception
// as an error.
@@ -13736,26 +13745,30 @@ if (__DEV__) {
return true;
}
var errorInfo = createCapturedValueAtFiber(value, sourceFiber);
var workInProgress = returnFiber;
do {
switch (workInProgress.tag) {
case HostRoot: {
var _errorInfo = value;
workInProgress.flags |= ShouldCapture;
var lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
var update = createRootErrorUpdate(
var _lane = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane);
var _update = createRootErrorUpdate(
workInProgress.stateNode,
_errorInfo,
lane
errorInfo,
_lane
);
enqueueCapturedUpdate(workInProgress, update);
enqueueCapturedUpdate(workInProgress, _update);
return false;
}
case ClassComponent:
var errorInfo = value;
// Capture and retry
var ctor = workInProgress.type;
var instance = workInProgress.stateNode;
@@ -13768,19 +13781,19 @@ if (__DEV__) {
) {
workInProgress.flags |= ShouldCapture;
var _lane = pickArbitraryLane(rootRenderLanes);
var _lane2 = pickArbitraryLane(rootRenderLanes);
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane2); // Schedule the error boundary to re-render using updated state
var _update = createClassErrorUpdate(_lane);
var _update2 = createClassErrorUpdate(_lane2);
initializeClassErrorUpdate(
_update,
_update2,
root,
workInProgress,
errorInfo
);
enqueueCapturedUpdate(workInProgress, _update);
enqueueCapturedUpdate(workInProgress, _update2);
return false;
}
@@ -15578,20 +15591,12 @@ if (__DEV__) {
function retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
recoverableError
renderLanes
) {
// Falling back to client rendering. Because this has performance
// implications, it's considered a recoverable error, even though the user
// likely won't observe anything wrong with the UI.
//
// The error is passed in as an argument to enforce that every caller provide
// a custom message, or explicitly opt out (currently the only path that opts
// out is legacy mode; every concurrent path provides an error).
if (recoverableError !== null) {
queueHydrationError(recoverableError);
} // This will add the old fiber to the deletion list
// This will add the old fiber to the deletion list
reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
var nextProps = workInProgress.pendingProps;
@@ -15677,9 +15682,7 @@ if (__DEV__) {
message = _getSuspenseInstanceF.message;
stack = _getSuspenseInstanceF.stack;
componentStack = _getSuspenseInstanceF.componentStack;
}
var capturedValue = null; // TODO: Figure out a better signal than encoding a magic digest value.
} // TODO: Figure out a better signal than encoding a magic digest value.
{
var error;
@@ -15697,17 +15700,17 @@ if (__DEV__) {
error.stack = stack || "";
error.digest = digest;
capturedValue = createCapturedValueFromError(
var capturedValue = createCapturedValueFromError(
error,
componentStack === undefined ? null : componentStack
);
queueHydrationError(capturedValue);
}
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
capturedValue
renderLanes
);
}
// any context has changed, we need to treat is as if the input might have changed.
@@ -15767,8 +15770,7 @@ if (__DEV__) {
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
null
renderLanes
);
} else if (isSuspenseInstancePending()) {
// This component is still pending more data from the server, so we can't hydrate its
@@ -15807,22 +15809,13 @@ if (__DEV__) {
// something either suspended or errored.
if (workInProgress.flags & ForceClientRender) {
// Something errored during hydration. Try again without hydrating.
// The error should've already been logged in throwException.
pushPrimaryTreeSuspenseHandler(workInProgress);
workInProgress.flags &= ~ForceClientRender;
var _capturedValue = createCapturedValueFromError(
new Error(
"There was an error while hydrating this Suspense boundary. " +
"Switched to client rendering."
),
null
);
return retrySuspenseComponentWithoutHydrating(
current,
workInProgress,
renderLanes,
_capturedValue
renderLanes
);
} else if (workInProgress.memoizedState !== null) {
// Something suspended and we should still be in dehydrated mode.
@@ -23897,11 +23890,12 @@ if (__DEV__) {
);
}
}
function renderDidError(error) {
function renderDidError() {
if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
workInProgressRootExitStatus = RootErrored;
}
}
function queueConcurrentError(error) {
if (workInProgressRootConcurrentErrors === null) {
workInProgressRootConcurrentErrors = [error];
} else {
@@ -26833,7 +26827,7 @@ if (__DEV__) {
return root;
}
var ReactVersion = "19.0.0-www-modern-ea7c02d5";
var ReactVersion = "19.0.0-www-modern-272ef63e";
// Might add PROFILE later.