-
-
Notifications
You must be signed in to change notification settings - Fork 629
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for replaying logs happen on async server operations #1649
Changes from all commits
585e5dc
2697ef7
4caf257
86d4262
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -105,16 +105,22 @@ function createResultObject(html: string | null, consoleReplayScript: string, re | |||||||||||||||||||||||||
|
||||||||||||||||||||||||||
async function createPromiseResult( | ||||||||||||||||||||||||||
renderState: RenderState & { result: Promise<string> }, | ||||||||||||||||||||||||||
consoleReplayScript: string, | ||||||||||||||||||||||||||
componentName: string, | ||||||||||||||||||||||||||
throwJsErrors: boolean | ||||||||||||||||||||||||||
): Promise<RenderResult> { | ||||||||||||||||||||||||||
// Capture console history before awaiting the promise | ||||||||||||||||||||||||||
// Node renderer will reset the global console.history after executing the synchronous part of the request. | ||||||||||||||||||||||||||
// It resets it only if replayServerAsyncOperationLogs renderer config is set to false. | ||||||||||||||||||||||||||
// In both cases, we need to keep a reference to console.history to avoid losing console logs in case of reset. | ||||||||||||||||||||||||||
const consoleHistory = console.history; | ||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||
const html = await renderState.result; | ||||||||||||||||||||||||||
const consoleReplayScript = buildConsoleReplay(consoleHistory); | ||||||||||||||||||||||||||
return createResultObject(html, consoleReplayScript, renderState); | ||||||||||||||||||||||||||
} catch (e: unknown) { | ||||||||||||||||||||||||||
const errorRenderState = handleRenderingError(e, { componentName, throwJsErrors }); | ||||||||||||||||||||||||||
return createResultObject(errorRenderState.result, consoleReplayScript, errorRenderState); | ||||||||||||||||||||||||||
const consoleReplayScript = buildConsoleReplay(consoleHistory); | ||||||||||||||||||||||||||
return createResultObject(errorRenderState.result, consoleReplayScript, renderState); | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
|
@@ -123,20 +129,12 @@ function createFinalResult( | |||||||||||||||||||||||||
componentName: string, | ||||||||||||||||||||||||||
throwJsErrors: boolean | ||||||||||||||||||||||||||
): null | string | Promise<RenderResult> { | ||||||||||||||||||||||||||
// Console history is stored globally in `console.history`. | ||||||||||||||||||||||||||
// If node renderer is handling a render request that returns a promise, | ||||||||||||||||||||||||||
// It can handle another request while awaiting the promise. | ||||||||||||||||||||||||||
// To prevent cross-request console logs leakage between these requests, | ||||||||||||||||||||||||||
// we build the consoleReplayScript before awaiting any promises. | ||||||||||||||||||||||||||
// The console history is reset after the synchronous part of each request. | ||||||||||||||||||||||||||
// This causes console logs happening during async operations to not be captured. | ||||||||||||||||||||||||||
const consoleReplayScript = buildConsoleReplay(); | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
const { result } = renderState; | ||||||||||||||||||||||||||
if (isPromise(result)) { | ||||||||||||||||||||||||||
return createPromiseResult({ ...renderState, result }, consoleReplayScript, componentName, throwJsErrors); | ||||||||||||||||||||||||||
return createPromiseResult({ ...renderState, result }, componentName, throwJsErrors); | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
const consoleReplayScript = buildConsoleReplay(); | ||||||||||||||||||||||||||
return JSON.stringify(createResultObject(result, consoleReplayScript, renderState)); | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
Comment on lines
+134
to
139
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inconsistent console history handling in The use of the spread operator in the For consistency with the promise case and to ensure all console logs are captured, consider modifying the - const consoleReplayScript = buildConsoleReplay();
+ const consoleReplayScript = buildConsoleReplay(console.history); This change ensures that all console logs are included in the replay script, regardless of whether the result is a promise or not. 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
|
@@ -188,6 +186,8 @@ const serverRenderReactComponent: typeof serverRenderReactComponentInternal = (o | |||||||||||||||||||||||||
} finally { | ||||||||||||||||||||||||||
// Reset console history after each render. | ||||||||||||||||||||||||||
// See `RubyEmbeddedJavaScript.console_polyfill` for initialization. | ||||||||||||||||||||||||||
// This is necessary when ExecJS and old versions of node renderer are used. | ||||||||||||||||||||||||||
// New versions of node renderer reset the console history automatically. | ||||||||||||||||||||||||||
console.history = []; | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent console log handling in non-promise scenarios.
The
buildConsoleReplay
call here doesn't use the captured console history, unlike in thecreatePromiseResult
function. This inconsistency may lead to loss of console logs in non-promise scenarios.Consider updating this line to use the captured console history:
This change would ensure consistent handling of console logs across all scenarios.
📝 Committable suggestion