Skip to content

Commit

Permalink
[Flight] Normalize Stack Using Fake Evals (#30401)
Browse files Browse the repository at this point in the history
Stacked on #30400 and
#30369

Previously we were using fake evals to recreate a stack for console
replaying and thrown errors. However, for owner stacks we just used the
raw string that came from the server.

This means that the format of the owner stack could include different
formats. Like Spidermonkey format for the client components and V8 for
the server components. This means that this stack can't be parsed
natively by the browser like when printing them as error like in
#30289. Additionally, since
there's no source file registered with that name and no source mapping
url, it can't be source mapped.

Before:

<img width="1329" alt="before-firefox"
src="https://github.com/user-attachments/assets/cbe03f9c-96ac-48fb-b58f-f3a224a774f4">

Instead, we need to create a fake stack like we do for the other things.
That way when it's printed as an Error it gets source mapped. It also
means that the format is consistently in the native format of the
current browser.

After:

<img width="753" alt="after-firefox"
src="https://github.com/user-attachments/assets/b436f1f5-ca37-4203-b29f-df9828c9fad3">

So this is nice because you can just take the result from
`captureOwnerStack()` and append it to an `Error` stack and print it
natively. E.g. this is what React DevTools will do.

If you want to parse and present it yourself though it's a bit awkward
though. The `captureOwnerStack()` API now includes a bunch of
`rsc://React/` URLs. These don't really have any direct connection to
the source map. Only the browser knows this connection from the eval.
You basically have to strip the prefix and then manually pass the
remainder to your own `findSourceMapURL`.

Another awkward part is that since Safari doesn't support eval sourceURL
exposed into `error.stack` - it means that `captureOwnerStack()` get an
empty location for server components since the fake eval doesn't work
there. That's not a big deal since these stacks are already broken even
for client modules for many because the `eval-source-map` strategy in
Webpack doesn't work in Safari for this same reason.

A lot of this refactoring is just clarifying that there's three kind of
ReactComponentInfo fields:

- `stack` - The raw stack as described on the original server.
- `debugStack` - The Error object containing the stack as represented in
the current client as fake evals.
- `debugTask` - The same thing as `debugStack` but described in terms of
a native `console.createTask`.

DiffTrain build for [b15c198](b15c198)
  • Loading branch information
sebmarkbage committed Jul 22, 2024
1 parent 97b42fd commit 48b7a7e
Show file tree
Hide file tree
Showing 35 changed files with 83 additions and 83 deletions.
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
792f1921145e51bd06b836ffa0a16ecc39c8ee82
b15c1983dcf96f19400b0ca7337be1e1fb1a8717
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION_TRANSFORMS
Original file line number Diff line number Diff line change
@@ -1 +1 @@
792f1921145e51bd06b836ffa0a16ecc39c8ee82
b15c1983dcf96f19400b0ca7337be1e1fb1a8717
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -1998,7 +1998,7 @@ __DEV__ &&
exports.useTransition = function () {
return resolveDispatcher().useTransition();
};
exports.version = "19.0.0-www-classic-792f1921-20240722";
exports.version = "19.0.0-www-classic-b15c1983-20240722";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -1978,7 +1978,7 @@ __DEV__ &&
exports.useTransition = function () {
return resolveDispatcher().useTransition();
};
exports.version = "19.0.0-www-modern-792f1921-20240722";
exports.version = "19.0.0-www-modern-b15c1983-20240722";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -669,4 +669,4 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactSharedInternals.H.useTransition();
};
exports.version = "19.0.0-www-classic-792f1921-20240722";
exports.version = "19.0.0-www-classic-b15c1983-20240722";
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -669,4 +669,4 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactSharedInternals.H.useTransition();
};
exports.version = "19.0.0-www-modern-792f1921-20240722";
exports.version = "19.0.0-www-modern-b15c1983-20240722";
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-profiling.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactSharedInternals.H.useTransition();
};
exports.version = "19.0.0-www-classic-792f1921-20240722";
exports.version = "19.0.0-www-classic-b15c1983-20240722";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-profiling.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactSharedInternals.H.useTransition();
};
exports.version = "19.0.0-www-modern-792f1921-20240722";
exports.version = "19.0.0-www-modern-b15c1983-20240722";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
4 changes: 2 additions & 2 deletions compiled/facebook-www/ReactART-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -17032,14 +17032,14 @@ __DEV__ &&
scheduleRoot: scheduleRoot,
setRefreshHandler: setRefreshHandler,
getCurrentFiber: getCurrentFiberForDevTools,
reconcilerVersion: "19.0.0-www-classic-792f1921-20240722"
reconcilerVersion: "19.0.0-www-classic-b15c1983-20240722"
});
})({
findFiberByHostInstance: function () {
return null;
},
bundleType: 1,
version: "19.0.0-www-classic-792f1921-20240722",
version: "19.0.0-www-classic-b15c1983-20240722",
rendererPackageName: "react-art"
});
var ClippingRectangle = TYPES.CLIPPING_RECTANGLE,
Expand Down
4 changes: 2 additions & 2 deletions compiled/facebook-www/ReactART-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -16443,14 +16443,14 @@ __DEV__ &&
scheduleRoot: scheduleRoot,
setRefreshHandler: setRefreshHandler,
getCurrentFiber: getCurrentFiberForDevTools,
reconcilerVersion: "19.0.0-www-modern-792f1921-20240722"
reconcilerVersion: "19.0.0-www-modern-b15c1983-20240722"
});
})({
findFiberByHostInstance: function () {
return null;
},
bundleType: 1,
version: "19.0.0-www-modern-792f1921-20240722",
version: "19.0.0-www-modern-b15c1983-20240722",
rendererPackageName: "react-art"
});
var ClippingRectangle = TYPES.CLIPPING_RECTANGLE,
Expand Down
4 changes: 2 additions & 2 deletions compiled/facebook-www/ReactART-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -10753,7 +10753,7 @@ var slice = Array.prototype.slice,
return null;
},
bundleType: 0,
version: "19.0.0-www-classic-792f1921-20240722",
version: "19.0.0-www-classic-b15c1983-20240722",
rendererPackageName: "react-art"
};
var internals$jscomp$inline_1386 = {
Expand Down Expand Up @@ -10784,7 +10784,7 @@ var internals$jscomp$inline_1386 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-www-classic-792f1921-20240722"
reconcilerVersion: "19.0.0-www-classic-b15c1983-20240722"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1387 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
4 changes: 2 additions & 2 deletions compiled/facebook-www/ReactART-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -10202,7 +10202,7 @@ var slice = Array.prototype.slice,
return null;
},
bundleType: 0,
version: "19.0.0-www-modern-792f1921-20240722",
version: "19.0.0-www-modern-b15c1983-20240722",
rendererPackageName: "react-art"
};
var internals$jscomp$inline_1372 = {
Expand Down Expand Up @@ -10233,7 +10233,7 @@ var internals$jscomp$inline_1372 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-www-modern-792f1921-20240722"
reconcilerVersion: "19.0.0-www-modern-b15c1983-20240722"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1373 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
10 changes: 5 additions & 5 deletions compiled/facebook-www/ReactDOM-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -27618,11 +27618,11 @@ __DEV__ &&
: flushSyncErrorInBuildsThatSupportLegacyMode;
(function () {
var isomorphicReactPackageVersion = React.version;
if ("19.0.0-www-classic-792f1921-20240722" !== isomorphicReactPackageVersion)
if ("19.0.0-www-classic-b15c1983-20240722" !== isomorphicReactPackageVersion)
throw Error(
'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' +
(isomorphicReactPackageVersion +
"\n - react-dom: 19.0.0-www-classic-792f1921-20240722\nLearn more: https://react.dev/warnings/version-mismatch")
"\n - react-dom: 19.0.0-www-classic-b15c1983-20240722\nLearn more: https://react.dev/warnings/version-mismatch")
);
})();
("function" === typeof Map &&
Expand Down Expand Up @@ -27688,12 +27688,12 @@ __DEV__ &&
scheduleRoot: scheduleRoot,
setRefreshHandler: setRefreshHandler,
getCurrentFiber: getCurrentFiberForDevTools,
reconcilerVersion: "19.0.0-www-classic-792f1921-20240722"
reconcilerVersion: "19.0.0-www-classic-b15c1983-20240722"
});
})({
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 1,
version: "19.0.0-www-classic-792f1921-20240722",
version: "19.0.0-www-classic-b15c1983-20240722",
rendererPackageName: "react-dom"
}) &&
canUseDOM &&
Expand Down Expand Up @@ -28336,7 +28336,7 @@ __DEV__ &&
exports.useFormStatus = function () {
return resolveDispatcher().useHostTransitionStatus();
};
exports.version = "19.0.0-www-classic-792f1921-20240722";
exports.version = "19.0.0-www-classic-b15c1983-20240722";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
10 changes: 5 additions & 5 deletions compiled/facebook-www/ReactDOM-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -26739,11 +26739,11 @@ __DEV__ &&
return_targetInst = null;
(function () {
var isomorphicReactPackageVersion = React.version;
if ("19.0.0-www-modern-792f1921-20240722" !== isomorphicReactPackageVersion)
if ("19.0.0-www-modern-b15c1983-20240722" !== isomorphicReactPackageVersion)
throw Error(
'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' +
(isomorphicReactPackageVersion +
"\n - react-dom: 19.0.0-www-modern-792f1921-20240722\nLearn more: https://react.dev/warnings/version-mismatch")
"\n - react-dom: 19.0.0-www-modern-b15c1983-20240722\nLearn more: https://react.dev/warnings/version-mismatch")
);
})();
("function" === typeof Map &&
Expand Down Expand Up @@ -26808,12 +26808,12 @@ __DEV__ &&
scheduleRoot: scheduleRoot,
setRefreshHandler: setRefreshHandler,
getCurrentFiber: getCurrentFiberForDevTools,
reconcilerVersion: "19.0.0-www-modern-792f1921-20240722"
reconcilerVersion: "19.0.0-www-modern-b15c1983-20240722"
});
})({
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 1,
version: "19.0.0-www-modern-792f1921-20240722",
version: "19.0.0-www-modern-b15c1983-20240722",
rendererPackageName: "react-dom"
}) &&
canUseDOM &&
Expand Down Expand Up @@ -27409,7 +27409,7 @@ __DEV__ &&
exports.useFormStatus = function () {
return resolveDispatcher().useHostTransitionStatus();
};
exports.version = "19.0.0-www-modern-792f1921-20240722";
exports.version = "19.0.0-www-modern-b15c1983-20240722";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
10 changes: 5 additions & 5 deletions compiled/facebook-www/ReactDOM-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -17223,14 +17223,14 @@ function getCrossOriginStringAs(as, input) {
}
var isomorphicReactPackageVersion$jscomp$inline_1771 = React.version;
if (
"19.0.0-www-classic-792f1921-20240722" !==
"19.0.0-www-classic-b15c1983-20240722" !==
isomorphicReactPackageVersion$jscomp$inline_1771
)
throw Error(
formatProdErrorMessage(
527,
isomorphicReactPackageVersion$jscomp$inline_1771,
"19.0.0-www-classic-792f1921-20240722"
"19.0.0-www-classic-b15c1983-20240722"
)
);
function flushSyncFromReconciler(fn) {
Expand Down Expand Up @@ -17276,7 +17276,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1778 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "19.0.0-www-classic-792f1921-20240722",
version: "19.0.0-www-classic-b15c1983-20240722",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2222 = {
Expand Down Expand Up @@ -17306,7 +17306,7 @@ var internals$jscomp$inline_2222 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-www-classic-792f1921-20240722"
reconcilerVersion: "19.0.0-www-classic-b15c1983-20240722"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2223 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down Expand Up @@ -17770,4 +17770,4 @@ exports.useFormState = function (action, initialState, permalink) {
exports.useFormStatus = function () {
return ReactSharedInternals.H.useHostTransitionStatus();
};
exports.version = "19.0.0-www-classic-792f1921-20240722";
exports.version = "19.0.0-www-classic-b15c1983-20240722";
10 changes: 5 additions & 5 deletions compiled/facebook-www/ReactDOM-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -16534,14 +16534,14 @@ function getCrossOriginStringAs(as, input) {
}
var isomorphicReactPackageVersion$jscomp$inline_1742 = React.version;
if (
"19.0.0-www-modern-792f1921-20240722" !==
"19.0.0-www-modern-b15c1983-20240722" !==
isomorphicReactPackageVersion$jscomp$inline_1742
)
throw Error(
formatProdErrorMessage(
527,
isomorphicReactPackageVersion$jscomp$inline_1742,
"19.0.0-www-modern-792f1921-20240722"
"19.0.0-www-modern-b15c1983-20240722"
)
);
Internals.findDOMNode = function (componentOrElement) {
Expand All @@ -16560,7 +16560,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1744 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "19.0.0-www-modern-792f1921-20240722",
version: "19.0.0-www-modern-b15c1983-20240722",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2213 = {
Expand Down Expand Up @@ -16590,7 +16590,7 @@ var internals$jscomp$inline_2213 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-www-modern-792f1921-20240722"
reconcilerVersion: "19.0.0-www-modern-b15c1983-20240722"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2214 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down Expand Up @@ -16961,4 +16961,4 @@ exports.useFormState = function (action, initialState, permalink) {
exports.useFormStatus = function () {
return ReactSharedInternals.H.useHostTransitionStatus();
};
exports.version = "19.0.0-www-modern-792f1921-20240722";
exports.version = "19.0.0-www-modern-b15c1983-20240722";
10 changes: 5 additions & 5 deletions compiled/facebook-www/ReactDOM-profiling.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -17994,14 +17994,14 @@ function getCrossOriginStringAs(as, input) {
}
var isomorphicReactPackageVersion$jscomp$inline_1858 = React.version;
if (
"19.0.0-www-classic-792f1921-20240722" !==
"19.0.0-www-classic-b15c1983-20240722" !==
isomorphicReactPackageVersion$jscomp$inline_1858
)
throw Error(
formatProdErrorMessage(
527,
isomorphicReactPackageVersion$jscomp$inline_1858,
"19.0.0-www-classic-792f1921-20240722"
"19.0.0-www-classic-b15c1983-20240722"
)
);
function flushSyncFromReconciler(fn) {
Expand Down Expand Up @@ -18047,7 +18047,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1865 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "19.0.0-www-classic-792f1921-20240722",
version: "19.0.0-www-classic-b15c1983-20240722",
rendererPackageName: "react-dom"
};
(function (internals) {
Expand Down Expand Up @@ -18091,7 +18091,7 @@ var devToolsConfig$jscomp$inline_1865 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-www-classic-792f1921-20240722"
reconcilerVersion: "19.0.0-www-classic-b15c1983-20240722"
});
function ReactDOMRoot(internalRoot) {
this._internalRoot = internalRoot;
Expand Down Expand Up @@ -18542,7 +18542,7 @@ exports.useFormState = function (action, initialState, permalink) {
exports.useFormStatus = function () {
return ReactSharedInternals.H.useHostTransitionStatus();
};
exports.version = "19.0.0-www-classic-792f1921-20240722";
exports.version = "19.0.0-www-classic-b15c1983-20240722";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
10 changes: 5 additions & 5 deletions compiled/facebook-www/ReactDOM-profiling.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -17288,14 +17288,14 @@ function getCrossOriginStringAs(as, input) {
}
var isomorphicReactPackageVersion$jscomp$inline_1829 = React.version;
if (
"19.0.0-www-modern-792f1921-20240722" !==
"19.0.0-www-modern-b15c1983-20240722" !==
isomorphicReactPackageVersion$jscomp$inline_1829
)
throw Error(
formatProdErrorMessage(
527,
isomorphicReactPackageVersion$jscomp$inline_1829,
"19.0.0-www-modern-792f1921-20240722"
"19.0.0-www-modern-b15c1983-20240722"
)
);
Internals.findDOMNode = function (componentOrElement) {
Expand All @@ -17314,7 +17314,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1831 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "19.0.0-www-modern-792f1921-20240722",
version: "19.0.0-www-modern-b15c1983-20240722",
rendererPackageName: "react-dom"
};
(function (internals) {
Expand Down Expand Up @@ -17358,7 +17358,7 @@ var devToolsConfig$jscomp$inline_1831 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-www-modern-792f1921-20240722"
reconcilerVersion: "19.0.0-www-modern-b15c1983-20240722"
});
function ReactDOMRoot(internalRoot) {
this._internalRoot = internalRoot;
Expand Down Expand Up @@ -17716,7 +17716,7 @@ exports.useFormState = function (action, initialState, permalink) {
exports.useFormStatus = function () {
return ReactSharedInternals.H.useHostTransitionStatus();
};
exports.version = "19.0.0-www-modern-792f1921-20240722";
exports.version = "19.0.0-www-modern-b15c1983-20240722";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
4 changes: 2 additions & 2 deletions compiled/facebook-www/ReactDOMServer-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -4563,7 +4563,7 @@ __DEV__ &&
parent: task.componentStack,
type: componentInfo,
owner: componentInfo.owner,
stack: componentInfo.stack
stack: null
});
}
}
Expand Down Expand Up @@ -8857,5 +8857,5 @@ __DEV__ &&
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
);
};
exports.version = "19.0.0-www-classic-792f1921-20240722";
exports.version = "19.0.0-www-classic-b15c1983-20240722";
})();
Loading

0 comments on commit 48b7a7e

Please sign in to comment.