Fix Node process crash in compressFileWithGZIP on unreadable PUT source#1454
Open
kartikgupta2607 wants to merge 1 commit into
Open
Conversation
compressFileWithGZIP piped the source through gzip with an 'error'-less promise that only resolved on 'finish', so a missing or unreadable source raised an unhandled stream 'error' that crashed the process while the promise never settled. Use stream.pipeline so a failure on any stream rejects the call and destroys every stream, surfacing as a failed PUT instead of terminating the process. Add unit tests: gzip round-trip (happy path) and rejection when the source file is missing. Signed-off-by: Kartik Gupta <kartikgupta2607@gmail.com>
kartikgupta2607
marked this pull request as ready for review
July 15, 2026 07:45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Description
FileUtil.compressFileWithGZIP(lib/file_util.js) pipes the source file through gzip into a temp file andawaits a promise that only listens for the writable'sfinishevent — none of the read/gzip/write streams has anerrorhandler. If the source file is missing or unreadable when aPUT ... AUTO_COMPRESS=TRUEruns, the read stream emits anerrorwith no listener, which Node escalates to anuncaughtExceptionthat crashes the whole process; the wrapping promise also never settles.This is reachable whenever a file disappears between when the
PUTfile list is resolved and when a given file is compressed (an external cleanup process, a race, or a path that no longer exists).Fix: use
stream.pipelinefromnode:stream/promises. It propagates an error from any stream in the chain into a single rejection and destroys every stream, so a missing/unreadable source now rejectscompressFileWithGZIP— which propagates through the existingtry/catchinuploadOneFileand surfaces as a failedPUT— instead of terminating the process. No behavior change on the success path.Minimal repro (crashes on current
master):Checklist
FileUtil.compressFileWithGZIP()tests: gzip round-trip + rejection when the source file is missing; the latter crashes the runner without this fix)npm run test:unit); prettier, oxlint andcheck-tspass. Integration tests not run locally (require a live account)CHANGELOG.md