scheduleRenewal() starts the renewal path from a timer with void this.start(). If reconnecting or replaying fails, the rejected promise is not handled at the timer boundary.
Evidence:
src/audio-manager.ts:229 creates the renewal timer
src/audio-manager.ts:230 calls void this.start() without catch handling
src/audio-manager.ts:92 and src/audio-manager.ts:113 can reject during the renewed start() path
Impact: renewal failures can become unhandled promise rejections and may leave the manager in an unclear state after a background reconnect attempt. This is especially hard to debug because the failure happens outside the original caller's start() call.
Acceptance Criteria
Renewal restart failures are caught at the timer boundary.
The manager cleans up partial connection/playback resources after a failed renewal attempt.
The failure is exposed in a minimal way, for example by emitting/logging through an optional callback or by setting a consistent state.
No new dependency is added.
Add a focused fake-timer test that makes the renewed start() path reject and verifies no unhandled rejection plus consistent final state.
## Description
`scheduleRenewal()` starts the renewal path from a timer with `void this.start()`. If reconnecting or replaying fails, the rejected promise is not handled at the timer boundary.
Evidence:
- `src/audio-manager.ts:229` creates the renewal timer
- `src/audio-manager.ts:230` calls `void this.start()` without catch handling
- `src/audio-manager.ts:92` and `src/audio-manager.ts:113` can reject during the renewed `start()` path
Impact: renewal failures can become unhandled promise rejections and may leave the manager in an unclear state after a background reconnect attempt. This is especially hard to debug because the failure happens outside the original caller's `start()` call.
## Acceptance Criteria
- Renewal restart failures are caught at the timer boundary.
- The manager cleans up partial connection/playback resources after a failed renewal attempt.
- The failure is exposed in a minimal way, for example by emitting/logging through an optional callback or by setting a consistent state.
- No new dependency is added.
- Add a focused fake-timer test that makes the renewed `start()` path reject and verifies no unhandled rejection plus consistent final state.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Description
scheduleRenewal()starts the renewal path from a timer withvoid this.start(). If reconnecting or replaying fails, the rejected promise is not handled at the timer boundary.Evidence:
src/audio-manager.ts:229creates the renewal timersrc/audio-manager.ts:230callsvoid this.start()without catch handlingsrc/audio-manager.ts:92andsrc/audio-manager.ts:113can reject during the renewedstart()pathImpact: renewal failures can become unhandled promise rejections and may leave the manager in an unclear state after a background reconnect attempt. This is especially hard to debug because the failure happens outside the original caller's
start()call.Acceptance Criteria
start()path reject and verifies no unhandled rejection plus consistent final state.