Skip to content

Commit 86b57e6

Browse files
committed
[Flight][Fiber] Encode owner in the error payload in dev and use it as the Error's Task (#34460)
When we report an error we typically log the owner stack of the thing that caught the error. Similarly we restore the `console.createTask` scope of the catching component when we call `reportError` or `console.error`. We also have a special case if something throws during reconciliation which uses the Server Component task as far as we got before we threw. https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactChildFiber.js#L1952-L1960 Chrome has since fixed it (on our request) that the Error constructor snapshots the Task at the time the constructor was created and logs that in `reportError`. This is a good thing since it means we get a coherent stack. Unfortunately, it means that the fake Errors that we create in Flight Client gets a snapshot of the task where they were created so when they're reported in the console they get the root Task instead of the Task of the handler of the error. Ideally we'd transfer the Task from the server and restore it. However, since we don't instrument the Error object to snapshot the owner and we can't read the native Task (if it's even enabled on the server) we don't actually have a correct snapshot to transfer for a Server Component Error. However, we can use the parent's task for where the error was observed by Flight Server and then encode that as a pseudo owner of the Error. Then we use this owner as the Task which the Error is created within. Now the client snapshots that Task which is reported by `reportError` so now we have an async stack for Server Component errors again. (Note that this owner may differ from the one observed by `captureOwnerStack` which gets the nearest Server Component from where it was caught. We could attach the owner to the Error object and use that owner when calling `onCaughtError`/`onUncaughtError`). Before: <img width="911" height="57" alt="Screenshot 2025-09-10 at 10 57 54 AM" src="https://github.com/user-attachments/assets/0446ef96-fad9-4e17-8a9a-d89c334233ec" /> After: <img width="910" height="128" alt="Screenshot 2025-09-10 at 11 06 20 AM" src="https://github.com/user-attachments/assets/b30e5892-cf40-4246-a588-0f309575439b" /> Similarly, there are Errors and warnings created by ChildFiber itself. Those execute in the scope of the general render of the parent Fiber. They used to get the scope of the nearest client component parent (e.g. div in this case) but that's the parent of the Server Component. It would be too expensive to run every level of reconciliation in its own task optimistically, so this does it only when we know that we'll throw or log an error that needs this context. Unfortunately this doesn't cover user space errors (such as if an iterable errors). Before: <img width="903" height="298" alt="Screenshot 2025-09-10 at 11 31 55 AM" src="https://github.com/user-attachments/assets/cffc94da-8c14-4d6e-9a5b-bf0833b8b762" /> After: <img width="1216" height="252" alt="Screenshot 2025-09-10 at 11 50 54 AM" src="https://github.com/user-attachments/assets/f85f93cf-ab73-4046-af3d-dd93b73b3552" /> <img width="412" height="115" alt="Screenshot 2025-09-10 at 11 52 46 AM" src="https://github.com/user-attachments/assets/a76cef7b-b162-4ecf-9b0a-68bf34afc239" /> DiffTrain build for [20e5431](20e5431)
1 parent 61de5a9 commit 86b57e6

34 files changed

+656
-316
lines changed

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0e10ee906e3ea55e4d717d4db498e1159235b06b
1+
20e5431747347796b3be8312e56cef655b26ef4d
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0e10ee906e3ea55e4d717d4db498e1159235b06b
1+
20e5431747347796b3be8312e56cef655b26ef4d

compiled/facebook-www/React-dev.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1418,7 +1418,7 @@ __DEV__ &&
14181418
exports.useTransition = function () {
14191419
return resolveDispatcher().useTransition();
14201420
};
1421-
exports.version = "19.2.0-www-classic-0e10ee90-20250912";
1421+
exports.version = "19.2.0-www-classic-20e54317-20250912";
14221422
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
14231423
"function" ===
14241424
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-dev.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1418,7 +1418,7 @@ __DEV__ &&
14181418
exports.useTransition = function () {
14191419
return resolveDispatcher().useTransition();
14201420
};
1421-
exports.version = "19.2.0-www-modern-0e10ee90-20250912";
1421+
exports.version = "19.2.0-www-modern-20e54317-20250912";
14221422
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
14231423
"function" ===
14241424
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-prod.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,4 +600,4 @@ exports.useSyncExternalStore = function (
600600
exports.useTransition = function () {
601601
return ReactSharedInternals.H.useTransition();
602602
};
603-
exports.version = "19.2.0-www-classic-0e10ee90-20250912";
603+
exports.version = "19.2.0-www-classic-20e54317-20250912";

compiled/facebook-www/React-prod.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,4 +600,4 @@ exports.useSyncExternalStore = function (
600600
exports.useTransition = function () {
601601
return ReactSharedInternals.H.useTransition();
602602
};
603-
exports.version = "19.2.0-www-modern-0e10ee90-20250912";
603+
exports.version = "19.2.0-www-modern-20e54317-20250912";

compiled/facebook-www/React-profiling.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ exports.useSyncExternalStore = function (
604604
exports.useTransition = function () {
605605
return ReactSharedInternals.H.useTransition();
606606
};
607-
exports.version = "19.2.0-www-classic-0e10ee90-20250912";
607+
exports.version = "19.2.0-www-classic-20e54317-20250912";
608608
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
609609
"function" ===
610610
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-profiling.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ exports.useSyncExternalStore = function (
604604
exports.useTransition = function () {
605605
return ReactSharedInternals.H.useTransition();
606606
};
607-
exports.version = "19.2.0-www-modern-0e10ee90-20250912";
607+
exports.version = "19.2.0-www-modern-20e54317-20250912";
608608
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
609609
"function" ===
610610
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/ReactART-dev.classic.js

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3784,6 +3784,16 @@ __DEV__ &&
37843784
: previousDebugInfo.concat(debugInfo));
37853785
return previousDebugInfo;
37863786
}
3787+
function getCurrentDebugTask() {
3788+
var debugInfo = currentDebugInfo;
3789+
if (null != debugInfo)
3790+
for (var i = debugInfo.length - 1; 0 <= i; i--)
3791+
if (null != debugInfo[i].name) {
3792+
var debugTask = debugInfo[i].debugTask;
3793+
if (null != debugTask) return debugTask;
3794+
}
3795+
return null;
3796+
}
37873797
function validateFragmentProps(element, fiber, returnFiber) {
37883798
for (var keys = Object.keys(element.props), i = 0; i < keys.length; i++) {
37893799
var key = keys[i];
@@ -3825,7 +3835,7 @@ __DEV__ &&
38253835
element = element.props.ref;
38263836
workInProgress.ref = void 0 !== element ? element : null;
38273837
}
3828-
function throwOnInvalidObjectType(returnFiber, newChild) {
3838+
function throwOnInvalidObjectTypeImpl(returnFiber, newChild) {
38293839
if (newChild.$$typeof === REACT_LEGACY_ELEMENT_TYPE)
38303840
throw Error(
38313841
'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.'
@@ -3839,7 +3849,15 @@ __DEV__ &&
38393849
"). If you meant to render a collection of children, use an array instead."
38403850
);
38413851
}
3842-
function warnOnFunctionType(returnFiber, invalidChild) {
3852+
function throwOnInvalidObjectType(returnFiber, newChild) {
3853+
var debugTask = getCurrentDebugTask();
3854+
null !== debugTask
3855+
? debugTask.run(
3856+
throwOnInvalidObjectTypeImpl.bind(null, returnFiber, newChild)
3857+
)
3858+
: throwOnInvalidObjectTypeImpl(returnFiber, newChild);
3859+
}
3860+
function warnOnFunctionTypeImpl(returnFiber, invalidChild) {
38433861
var parentName = getComponentNameFromFiber(returnFiber) || "Component";
38443862
ownerHasFunctionTypeWarning[parentName] ||
38453863
((ownerHasFunctionTypeWarning[parentName] = !0),
@@ -3861,7 +3879,15 @@ __DEV__ &&
38613879
parentName
38623880
));
38633881
}
3864-
function warnOnSymbolType(returnFiber, invalidChild) {
3882+
function warnOnFunctionType(returnFiber, invalidChild) {
3883+
var debugTask = getCurrentDebugTask();
3884+
null !== debugTask
3885+
? debugTask.run(
3886+
warnOnFunctionTypeImpl.bind(null, returnFiber, invalidChild)
3887+
)
3888+
: warnOnFunctionTypeImpl(returnFiber, invalidChild);
3889+
}
3890+
function warnOnSymbolTypeImpl(returnFiber, invalidChild) {
38653891
var parentName = getComponentNameFromFiber(returnFiber) || "Component";
38663892
ownerHasSymbolTypeWarning[parentName] ||
38673893
((ownerHasSymbolTypeWarning[parentName] = !0),
@@ -3878,6 +3904,14 @@ __DEV__ &&
38783904
parentName
38793905
));
38803906
}
3907+
function warnOnSymbolType(returnFiber, invalidChild) {
3908+
var debugTask = getCurrentDebugTask();
3909+
null !== debugTask
3910+
? debugTask.run(
3911+
warnOnSymbolTypeImpl.bind(null, returnFiber, invalidChild)
3912+
)
3913+
: warnOnSymbolTypeImpl(returnFiber, invalidChild);
3914+
}
38813915
function createChildReconciler(shouldTrackSideEffects) {
38823916
function deleteChild(returnFiber, childToDelete) {
38833917
if (shouldTrackSideEffects) {
@@ -19720,10 +19754,10 @@ __DEV__ &&
1972019754
(function () {
1972119755
var internals = {
1972219756
bundleType: 1,
19723-
version: "19.2.0-www-classic-0e10ee90-20250912",
19757+
version: "19.2.0-www-classic-20e54317-20250912",
1972419758
rendererPackageName: "react-art",
1972519759
currentDispatcherRef: ReactSharedInternals,
19726-
reconcilerVersion: "19.2.0-www-classic-0e10ee90-20250912"
19760+
reconcilerVersion: "19.2.0-www-classic-20e54317-20250912"
1972719761
};
1972819762
internals.overrideHookState = overrideHookState;
1972919763
internals.overrideHookStateDeletePath = overrideHookStateDeletePath;
@@ -19757,7 +19791,7 @@ __DEV__ &&
1975719791
exports.Shape = Shape;
1975819792
exports.Surface = Surface;
1975919793
exports.Text = Text;
19760-
exports.version = "19.2.0-www-classic-0e10ee90-20250912";
19794+
exports.version = "19.2.0-www-classic-20e54317-20250912";
1976119795
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
1976219796
"function" ===
1976319797
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/ReactART-dev.modern.js

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3690,6 +3690,16 @@ __DEV__ &&
36903690
: previousDebugInfo.concat(debugInfo));
36913691
return previousDebugInfo;
36923692
}
3693+
function getCurrentDebugTask() {
3694+
var debugInfo = currentDebugInfo;
3695+
if (null != debugInfo)
3696+
for (var i = debugInfo.length - 1; 0 <= i; i--)
3697+
if (null != debugInfo[i].name) {
3698+
var debugTask = debugInfo[i].debugTask;
3699+
if (null != debugTask) return debugTask;
3700+
}
3701+
return null;
3702+
}
36933703
function validateFragmentProps(element, fiber, returnFiber) {
36943704
for (var keys = Object.keys(element.props), i = 0; i < keys.length; i++) {
36953705
var key = keys[i];
@@ -3731,7 +3741,7 @@ __DEV__ &&
37313741
element = element.props.ref;
37323742
workInProgress.ref = void 0 !== element ? element : null;
37333743
}
3734-
function throwOnInvalidObjectType(returnFiber, newChild) {
3744+
function throwOnInvalidObjectTypeImpl(returnFiber, newChild) {
37353745
if (newChild.$$typeof === REACT_LEGACY_ELEMENT_TYPE)
37363746
throw Error(
37373747
'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.'
@@ -3745,7 +3755,15 @@ __DEV__ &&
37453755
"). If you meant to render a collection of children, use an array instead."
37463756
);
37473757
}
3748-
function warnOnFunctionType(returnFiber, invalidChild) {
3758+
function throwOnInvalidObjectType(returnFiber, newChild) {
3759+
var debugTask = getCurrentDebugTask();
3760+
null !== debugTask
3761+
? debugTask.run(
3762+
throwOnInvalidObjectTypeImpl.bind(null, returnFiber, newChild)
3763+
)
3764+
: throwOnInvalidObjectTypeImpl(returnFiber, newChild);
3765+
}
3766+
function warnOnFunctionTypeImpl(returnFiber, invalidChild) {
37493767
var parentName = getComponentNameFromFiber(returnFiber) || "Component";
37503768
ownerHasFunctionTypeWarning[parentName] ||
37513769
((ownerHasFunctionTypeWarning[parentName] = !0),
@@ -3767,7 +3785,15 @@ __DEV__ &&
37673785
parentName
37683786
));
37693787
}
3770-
function warnOnSymbolType(returnFiber, invalidChild) {
3788+
function warnOnFunctionType(returnFiber, invalidChild) {
3789+
var debugTask = getCurrentDebugTask();
3790+
null !== debugTask
3791+
? debugTask.run(
3792+
warnOnFunctionTypeImpl.bind(null, returnFiber, invalidChild)
3793+
)
3794+
: warnOnFunctionTypeImpl(returnFiber, invalidChild);
3795+
}
3796+
function warnOnSymbolTypeImpl(returnFiber, invalidChild) {
37713797
var parentName = getComponentNameFromFiber(returnFiber) || "Component";
37723798
ownerHasSymbolTypeWarning[parentName] ||
37733799
((ownerHasSymbolTypeWarning[parentName] = !0),
@@ -3784,6 +3810,14 @@ __DEV__ &&
37843810
parentName
37853811
));
37863812
}
3813+
function warnOnSymbolType(returnFiber, invalidChild) {
3814+
var debugTask = getCurrentDebugTask();
3815+
null !== debugTask
3816+
? debugTask.run(
3817+
warnOnSymbolTypeImpl.bind(null, returnFiber, invalidChild)
3818+
)
3819+
: warnOnSymbolTypeImpl(returnFiber, invalidChild);
3820+
}
37873821
function createChildReconciler(shouldTrackSideEffects) {
37883822
function deleteChild(returnFiber, childToDelete) {
37893823
if (shouldTrackSideEffects) {
@@ -19491,10 +19525,10 @@ __DEV__ &&
1949119525
(function () {
1949219526
var internals = {
1949319527
bundleType: 1,
19494-
version: "19.2.0-www-modern-0e10ee90-20250912",
19528+
version: "19.2.0-www-modern-20e54317-20250912",
1949519529
rendererPackageName: "react-art",
1949619530
currentDispatcherRef: ReactSharedInternals,
19497-
reconcilerVersion: "19.2.0-www-modern-0e10ee90-20250912"
19531+
reconcilerVersion: "19.2.0-www-modern-20e54317-20250912"
1949819532
};
1949919533
internals.overrideHookState = overrideHookState;
1950019534
internals.overrideHookStateDeletePath = overrideHookStateDeletePath;
@@ -19528,7 +19562,7 @@ __DEV__ &&
1952819562
exports.Shape = Shape;
1952919563
exports.Surface = Surface;
1953019564
exports.Text = Text;
19531-
exports.version = "19.2.0-www-modern-0e10ee90-20250912";
19565+
exports.version = "19.2.0-www-modern-20e54317-20250912";
1953219566
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
1953319567
"function" ===
1953419568
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

0 commit comments

Comments
 (0)