feat: Guard against unbounded synchronous promise chain recursion#527
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a safety guard to the synchronous promise reaction processor so deeply (or recursively) chained synchronous continuations can’t grow the call stack without bound, by forcing a microtask hop once a configurable chain depth is exceeded.
Changes:
- Introduces a configurable max synchronous chain depth and enforces it in
syncItemProcessorvia_runPendingItem. - Exposes the new configuration API (
setMaxSyncPromiseChainDepth) from the package entrypoint. - Adds targeted tests covering shallow chains, very deep chains (no stack overflow), forced microtask hop behavior, and disabling/resetting the guard.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| lib/src/promise/itemProcessor.ts | Adds depth tracking + guard logic and a new setter to configure the max synchronous chain depth. |
| lib/src/index.ts | Re-exports setMaxSyncPromiseChainDepth as a public API. |
| lib/test/src/promise/syncChainDepth.test.ts | Adds regression and behavior tests for deep/recursive sync promise chains and configuration options. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #527 +/- ##
==========================================
- Coverage 97.57% 97.55% -0.02%
==========================================
Files 28 28
Lines 1484 1516 +32
Branches 350 358 +8
==========================================
+ Hits 1448 1479 +31
- Misses 36 37 +1
🚀 New features to boost your workflow:
|
c0f1ec3 to
762c310
Compare
Resolving a very deep or "hostile" self-resolving thenable through createSyncPromise could grow the call stack without bound and overflow it. syncItemProcessor now tracks consecutive synchronous continuations and forces a microtask hop once a configurable depth setMaxSyncPromiseChainDepth, default 200) is exceeded, letting the stack unwind before continuing.
nevware21-bot
approved these changes
Jul 8, 2026
nevware21-bot
left a comment
Contributor
There was a problem hiding this comment.
Approved by nevware21-bot
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.
Resolving a very deep or "hostile" self-resolving thenable through createSyncPromise could grow the call stack without bound and overflow it. syncItemProcessor now tracks consecutive synchronous continuations and forces a microtask hop once a configurable depth setMaxSyncPromiseChainDepth, default 200) is exceeded, letting the stack unwind before continuing.