Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
β‘ Bolt: [performance improvement] Refactor preview server to use asynchronous I/O #89
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
Uh oh!
There was an error while loading. Please reload this page.
β‘ Bolt: [performance improvement] Refactor preview server to use asynchronous I/O #89
Changes from all commits
90630ffFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
There are no files selected for viewing
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.
π§© Analysis chain
π Script executed:
cat -n packages/desktop/src/main/preview-server.ts | head -150Repository: iotserver24/Xibecode
Length of output: 4504
Handle rejected promises from the async request handler.
Line 82 makes
handleRequestasynchronous, but line 45 invokes it without awaiting or catching the returned promise. Any uncaught error inhandleRequestbecomes an unhandled promise rejection, leaving requests without a proper response.Suggested fix
π€ Prompt for AI Agents
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.
π§© Analysis chain
π Script executed:
Repository: iotserver24/Xibecode
Length of output: 110
π Script executed:
sed -n '115,135p' ./packages/desktop/src/main/preview-server.tsRepository: iotserver24/Xibecode
Length of output: 681
π Web query:
Node.js res.end() after headersSent true behaviorπ‘ Result:
In Node.js, calling res.end when headersSent is true is a standard and safe operation [1][2]. The res.end method is the required finalizer for an HTTP response; it signals to the server that all headers and body data have been sent and that the response is complete [3][4]. When res.end is called: - If headers have not yet been sent (headersSent is false), Node.js will automatically send them before finalizing the response [1][5]. - If headers have already been sent (headersSent is true), res.end simply completes the response stream [1][3]. The common error ERR_HTTP_HEADERS_SENT occurs not because of calling res.end when headers are already sent, but because of attempting to modify headers (e.g., using res.setHeader or res.writeHead) or sending additional response data after the response has already been finalized [6][7][2]. Best practices for handling this state include: - Checking res.headersSent before attempting to set headers or send error responses in asynchronous code paths [2][8]. - Ensuring that each request handler has exactly one response path to avoid attempting to send multiple responses [7][2]. - Using return statements after calling res.end or other response-sending methods to prevent subsequent code from executing and attempting to modify the already-sent response [1][2][9].
Citations:
π Web query:
Node.js stream error handler res.destroy vs res.end when pipingπ‘ Result:
When piping streams in Node.js, the choice between res.destroy and res.end depends on the context of the error and the state of the response [1][2]. The.pipe method does not automatically propagate errors or clean up streams [3][4]. If an error occurs in a piped stream, the destination (such as an HTTP response) is often left hanging, keeping the socket open and the client waiting [1][5]. res.destroy(err) Use this when a fatal error occurs that prevents the response from completing successfully [6][5]. Calling.destroy immediately closes the underlying socket, which is appropriate if you cannot send a valid response body or if the stream is in an invalid state [6][5]. It signals that the connection should be terminated abruptly [5]. res.end Use this when you need to gracefully terminate the response, typically after you have already sent some data or when you want to send a final error message (e.g., a 500 status code) before closing [1][2]. If headers have not been sent, you can set an error status code and then call.end to inform the client of the failure [5]. Best Practice: Use stream.pipeline The modern, recommended approach is to use stream.pipeline instead of.pipe [3][7][4]. The pipeline utility automatically handles error propagation and cleanup [4]. When an error occurs, it automatically calls.destroy on all streams in the pipeline, preventing resource leaks and hanging sockets [4]. Example using pipeline: const { pipeline } = require('node:stream'); pipeline(sourceStream, res, (err) => { if (err) { console.error('Pipeline failed:', err); // If headers haven't been sent, you can send a 500 error if (!res.headersSent) { res.statusCode = 500; res.end('Internal Server Error'); } else { // Otherwise, destroy the response to close the connection res.destroy(err); } } }); In summary, prefer pipeline to avoid manual error handling [3][8]. If you must use.pipe, you are responsible for manually attaching error listeners to all streams and deciding whether to call.end (for a graceful, potentially error-informed close) or.destroy (for an immediate, forced termination) based on whether headers have already been sent [1][3][5].
Citations:
π Script executed:
Repository: iotserver24/Xibecode
Length of output: 857
Move the error response body inside the headersSent check.
Line 125 unconditionally calls
res.end('Failed to read file')even whenheadersSentis true. If the stream errors after piping begins (after theopenevent at line 127), this appends a string to the binary response, corrupting the downloaded file. When headers are already sent, destroy the response instead.Suggested fix
readStream.on('error', (err) => { if (!res.headersSent) { res.writeHead(500); res.end('Failed to read file'); return; } res.destroy(err); });π Committable suggestion
π€ Prompt for AI Agents
Uh oh!
There was an error while loading. Please reload this page.