Skip to content

@tus/s3-store: ensure promise rejection isn't uncaught#812

Merged
Murderlon merged 1 commit intotus:mainfrom
itslenny:fix/catch-deferred-promise-rejections
Mar 25, 2026
Merged

@tus/s3-store: ensure promise rejection isn't uncaught#812
Murderlon merged 1 commit intotus:mainfrom
itslenny:fix/catch-deferred-promise-rejections

Conversation

@itslenny
Copy link
Contributor

This PR fixes a fairly rare uncaught exception issue that I've had occur in production resulting in a fatal error / node crash. I can reproduce this locally by doing TUS uploads and intentionally disrupting traffic to S3.

This issue occurs when one of the deferred promises throws before getting to the Promise.all which node identifies as an uncaught exception. This only happens if pendingChunkFilepath is not null in the catch block which causes the async operation await fsProm.rm(pendingChunkFilepath) to run which advances the event loop causing node to recognize the uncaught exception before Promise.all is awaited.

I've also added a test that reproduces the issue consistently. You can comment out my fix and run the new test to see the uncaught exception.

@changeset-bot
Copy link

changeset-bot bot commented Mar 25, 2026

🦋 Changeset detected

Latest commit: f983077

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@tus/s3-store Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Mar 25, 2026

Walkthrough

Changes were made to prevent unhandled promise rejections in the S3Store's uploadParts method by adding a .catch() handler to deferred promises. A new test case verifies that no unhandled rejections occur when uploads fail, and a changeset file documents the patch version bump.

Changes

Cohort / File(s) Summary
Metadata
.changeset/modern-spoons-behave.md
Added changeset entry for @tus/s3-store with patch version bump documenting deferred promise rejection handling.
Promise Rejection Handling
packages/s3-store/src/index.ts
Added .catch(() => { /\* ignore \*/ }) handler to per-chunk deferred promises in uploadParts to prevent unhandled rejections before the later Promise.all* call.
Test Coverage
packages/s3-store/src/test/index.ts
Added test case verifying no unhandledRejection event is triggered when an upload fails quickly, using stubbed uploadPart method and a self-destroying readable stream.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The PR description provides clear context about the issue (uncaught exception in production), root cause (deferred promise rejection before Promise.all, with async operation advancing event loop), and solution, plus mentions a test that reproduces the issue.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The PR title clearly and specifically describes the main change: preventing uncaught promise rejections in the S3 store implementation, which matches the primary objective of fixing a fatal Node process crash caused by unhandled promise rejections.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@itslenny itslenny deployed to external-testing March 25, 2026 09:52 — with GitHub Actions Active
@Murderlon Murderlon changed the title fix: ensure promise rejection isn't uncaught @tus/s3-store: ensure promise rejection isn't uncaught Mar 25, 2026
Copy link
Member

@Murderlon Murderlon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! Thanks

@Murderlon Murderlon merged commit 0ad6c02 into tus:main Mar 25, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants