Async utilities count swallowed retryer failures as successes and call onSuccess(undefined)
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- typescript
- Domain
- tooling
Research direction
Start at AsyncRetryer.execute and trace how AsyncDebouncer, AsyncThrottler, AsyncRateLimiter, AsyncQueuer, and AsyncBatcher handle its resolved undefined value. Reproduce disabled, swallowed-failure, and aborted executions, then define and verify the intended success, error, callback, and count behavior across all five utilities.
Written by the indexing model from the issue text.
Description
Describe the bug
AsyncRetryer.execute resolves undefined in three non-success cases: the retryer is disabled (enabled: false), all attempts failed with retryer-level throwOnError: false, or the execution was aborted.
Every async utility that wraps an internal retryer (AsyncDebouncer, AsyncThrottler, AsyncRateLimiter, AsyncQueuer, AsyncBatcher) treats that resolved undefined as a success: successCount increments, lastResult is overwritten with undefined, and onSuccess fires with undefined as the result — e.g. onSuccess: (result: string) => ... receives undefined at runtime.
Repro sketch:
const debouncer = new AsyncDebouncer(
async () => { throw new Error('always fails') },
{
wait: 100,
asyncRetryerOptions: { maxAttempts: 2, throwOnError: false },
onSuccess: (result) => console.log('success?', result), // fires with undefined
},
)
Design questions to settle
- Should a swallowed final failure settle as an error at the parent level (increment
errorCount, fireonError) even though the retryer didn't throw? - Should an aborted execution count as neither success nor error (probably — it already returns early in some paths)?
AsyncRetryer.execute'sundefinedreturn is ambiguous by design; distinguishing outcomes may need an internal result envelope or reading the retryer's final state (lastError) afterexecuteresolves.
Noted during review of #246 (see CodeRabbit feedback there) — split out because the fix changes observable semantics across all five utilities rather than being a bugfix in one.
🤖 Generated with Claude Code
- Dominant language
- TypeScript
- Stars
- 769
- Forks
- 64
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 3
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from TanStack/pacer
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 3/5 1-2 days Newbie friendliness 75/100
-
Difficulty 3/5 1-2 days Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 35/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug clawsweeper:linked-pr-open clawsweeper:needs-live-repro clawsweeper:no-new-fix-pr impact:message-loss issue-rating: 🐚 platinum hermit P2 regression
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
danielmiessler/LifeOS#2218 ·