Absorb the AbortError that priming the voice clip provokes - #158
Merged
Conversation
The first pointer press of every match logged an uncaught error: AbortError: The play() request was interrupted by a call to pause(). createRecordedSpeech's prime() spends the browser's first user gesture on the recorded-voice clip so a later beat is allowed to play. It sets a silent src, calls play(), and immediately pauses. That pause is the point of the exercise and it rejects the play it interrupts — but `void target.play()` discarded the promise, so an expected rejection surfaced as an unhandled one. Nothing was broken: priming worked and the silence was intended. The error was alarming, fired on the first press of every match, and landed in the middle of the event sequence anyone debugging input is reading — it cost real time during the pause-button investigation by looking like part of a dead button. Attach a catch, keeping the behaviour identical. speak() already handles its own play() promise and cancel()/stopClip() are covered by the generation guard, so prime() was the only unhandled path; a genuine autoplay refusal is still acted on where it matters. Verified in a browser: three presses across a match now produce an empty console where the first press previously logged the AbortError. The new test fails against the old prime(). Closes #156 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BoQrnJcCawJvZ9jGHx5W4P Signed-off-by: Claude <knorcedger@gmail.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
What changed?
The first pointer press of every match logged an uncaught error to the console:
createRecordedSpeech(...).prime()spends the browser's first user gesture on the recorded-voiceclip so a later beat is allowed to play: it sets a silent
src, callsplay(), and immediatelypauses. That pause is the whole point, and it rejects the
play()it interrupts — butvoid target.play()discarded the promise, so an expected rejection surfaced as an unhandled one.Attaching a
.catchkeeps the behaviour identical and takes the error out of the console.speak()already handles its own
play()promise andcancel()/stopClip()are covered by the generationguard, so
prime()was the only unhandled path; a genuine autoplay refusal is still acted on whereit matters.
Related issue
Closes #156
Why this approach?
Nothing was actually broken — priming worked and the silence was intended. The case for fixing it is
that the error is alarming, fires on the first press of every match, and lands in the middle of the
event sequence anyone debugging input is reading. It cost real time during #153 by appearing to be
part of a dead pause button.
Suppressing the rejection at its source is preferable to a global
unhandledrejectionfilter, whichwould hide genuine audio failures too.
Verification
Driven in a real browser: three pause presses across a match, including the first gesture.
AbortError: The play() request was interrupted by a call to pause()on the first pressThe new test was confirmed to fail against the old
prime()and pass against the new one, so itgenuinely guards the regression.
npm run typechecknpm test— 1401 passed, 11 skippednpm run build,npm run bundle:check,npm run bundle:self-testprime()whoseplay()rejects producesno unhandled rejection, and still plays the silent clip, pauses it, and primes the fallback
is the evidence
Provenance and AI assistance
Claude Code (Claude Opus) diagnosed, fixed, and tested this. No generated assets are included.
Contributor checklist
CONTRIBUTING.mdand followed the deterministic simulation rulesgit commit -s)🤖 Generated with Claude Code
https://claude.ai/code/session_01BoQrnJcCawJvZ9jGHx5W4P
Generated by Claude Code