From 0f6c76c65b28a5834f144cf46bd747a0625626bd Mon Sep 17 00:00:00 2001 From: Sebastian Sebbie Silbermann Date: Sat, 5 Jul 2025 17:03:17 +0200 Subject: [PATCH] [Flight] Consistent format of virtual `rsc:` sources `filterStackFrame` was called with a sourceURL that didn't reflect the original sourceURL. This breaks once you try to use `findSourceMapURL` on the given sourceURL since the encoding would be off. --- packages/react-client/src/ReactFlightReplyClient.js | 2 +- packages/react-client/src/__tests__/ReactFlight-test.js | 8 +++++++- packages/react-server/src/ReactFlightServer.js | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/react-client/src/ReactFlightReplyClient.js b/packages/react-client/src/ReactFlightReplyClient.js index 40de7ca51e4..d22a894b515 100644 --- a/packages/react-client/src/ReactFlightReplyClient.js +++ b/packages/react-client/src/ReactFlightReplyClient.js @@ -1106,7 +1106,7 @@ function createFakeServerFunction, T>( '\n//# sourceURL=rsc://React/' + encodeURIComponent(environmentName) + '/' + - filename + + encodeURI(filename) + '?s' + // We add an extra s here to distinguish from the fake stack frames fakeServerFunctionIdx++; code += '\n//# sourceMappingURL=' + sourceMap; diff --git a/packages/react-client/src/__tests__/ReactFlight-test.js b/packages/react-client/src/__tests__/ReactFlight-test.js index d77bcea346b..d79977beec0 100644 --- a/packages/react-client/src/__tests__/ReactFlight-test.js +++ b/packages/react-client/src/__tests__/ReactFlight-test.js @@ -1306,6 +1306,9 @@ describe('ReactFlight', () => { ' at file:///testing.js:42:3', // async anon function (https://github.com/ChromeDevTools/devtools-frontend/blob/831be28facb4e85de5ee8c1acc4d98dfeda7a73b/test/unittests/front_end/panels/console/ErrorStackParser_test.ts#L130C9-L130C41) ' at async file:///testing.js:42:3', + // third-party RSC frame + // Ideally this would be a real frame produced by React not a mocked one. + ' at ThirdParty (rsc://React/ThirdParty/file:///code/%5Broot%2520of%2520the%2520server%5D.js?42:1:1)', // host component in parent stack ' at div ()', ...originalStackLines.slice(2), @@ -1360,7 +1363,10 @@ describe('ReactFlight', () => { return functionName === 'div'; } return ( - !filename.startsWith('node:') && !filename.includes('node_modules') + !filename.startsWith('node:') && + !filename.includes('node_modules') && + // sourceURL from an ES module in `/code/[root of the server].js` + filename !== 'file:///code/[root%20of%20the%20server].js' ); }, }); diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index 35c25b18901..d599a0b321c 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -184,10 +184,10 @@ function devirtualizeURL(url: string): string { // We need to reverse it back into the original location by stripping its prefix // and suffix. We don't need the environment name because it's available on the // parent object that will contain the stack. - const envIdx = url.indexOf('/', 12); + const envIdx = url.indexOf('/', 'rsc://React/'.length); const suffixIdx = url.lastIndexOf('?'); if (envIdx > -1 && suffixIdx > -1) { - return url.slice(envIdx + 1, suffixIdx); + return decodeURI(url.slice(envIdx + 1, suffixIdx)); } } return url;