Skip to content

Commit 0361411

Browse files
committed
Don't replay consoles written inside onError/onPostpone.
These aren't conceptually part of the request's render so we exit the request context for those.
1 parent c054691 commit 0361411

File tree

2 files changed

+68
-4
lines changed

2 files changed

+68
-4
lines changed

packages/react-client/src/__tests__/ReactFlight-test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,4 +1978,45 @@ describe('ReactFlight', () => {
19781978
</div>,
19791979
);
19801980
});
1981+
1982+
// @gate enableServerComponentLogs
1983+
it('replays logs, but not onError logs', async () => {
1984+
function foo() {
1985+
return 'hello';
1986+
}
1987+
function ServerComponent() {
1988+
console.log('hi', {prop: 123, fn: foo});
1989+
throw new Error('err');
1990+
}
1991+
1992+
let transport;
1993+
expect(() => {
1994+
// Reset the modules so that we get a new overridden console on top of the
1995+
// one installed by expect. This ensures that we still emit console.error
1996+
// calls.
1997+
jest.resetModules();
1998+
jest.mock('react', () => require('react/react.react-server'));
1999+
ReactServer = require('react');
2000+
ReactNoopFlightServer = require('react-noop-renderer/flight-server');
2001+
transport = ReactNoopFlightServer.render({root: <ServerComponent />});
2002+
}).toErrorDev('err');
2003+
2004+
const log = console.log;
2005+
try {
2006+
console.log = jest.fn();
2007+
// The error should not actually get logged because we're not awaiting the root
2008+
// so it's not thrown but the server log also shouldn't be replayed.
2009+
await ReactNoopFlightClient.read(transport);
2010+
2011+
expect(console.log).toHaveBeenCalledTimes(1);
2012+
expect(console.log.mock.calls[0][0]).toBe('hi');
2013+
expect(console.log.mock.calls[0][1].prop).toBe(123);
2014+
const loggedFn = console.log.mock.calls[0][1].fn;
2015+
expect(typeof loggedFn).toBe('function');
2016+
expect(loggedFn).not.toBe(foo);
2017+
expect(loggedFn.toString()).toBe(foo.toString());
2018+
} finally {
2019+
console.log = log;
2020+
}
2021+
});
19812022
});

packages/react-server/src/ReactFlightServer.js

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,13 +1689,36 @@ function renderModelDestructive(
16891689
}
16901690

16911691
function logPostpone(request: Request, reason: string): void {
1692-
const onPostpone = request.onPostpone;
1693-
onPostpone(reason);
1692+
const prevRequest = currentRequest;
1693+
currentRequest = null;
1694+
try {
1695+
const onPostpone = request.onPostpone;
1696+
if (supportsRequestStorage) {
1697+
// Exit the request context while running callbacks.
1698+
requestStorage.run(undefined, onPostpone, reason);
1699+
} else {
1700+
onPostpone(reason);
1701+
}
1702+
} finally {
1703+
currentRequest = prevRequest;
1704+
}
16941705
}
16951706

16961707
function logRecoverableError(request: Request, error: mixed): string {
1697-
const onError = request.onError;
1698-
const errorDigest = onError(error);
1708+
const prevRequest = currentRequest;
1709+
currentRequest = null;
1710+
let errorDigest;
1711+
try {
1712+
const onError = request.onError;
1713+
if (supportsRequestStorage && false) {
1714+
// Exit the request context while running callbacks.
1715+
errorDigest = requestStorage.run(undefined, onError, error);
1716+
} else {
1717+
errorDigest = onError(error);
1718+
}
1719+
} finally {
1720+
currentRequest = prevRequest;
1721+
}
16991722
if (errorDigest != null && typeof errorDigest !== 'string') {
17001723
// eslint-disable-next-line react-internal/prod-error-codes
17011724
throw new Error(

0 commit comments

Comments
 (0)