Skip to content

fix(bot): report a dead autoplay replenish at error level - #2063

Merged
LucasSantana-Dev merged 2 commits into
mainfrom
fix/player-recovery-observability
Aug 21, 2026
Merged

LucasSantana-Dev merged 2 commits into
mainfrom
fix/player-recovery-observability

Conversation

@LucasSantana-Dev

@LucasSantana-Dev LucasSantana-Dev commented Aug 21, 2026 •

Copy link
Copy Markdown
Owner

Closes #1995.

Problem

trackHandlers.ts:204-214 — when the first replenish fails, a retry is scheduled 5s later. If the retry also fails, autoplay has stopped for that guild and nothing will try again. It was only warnLog'd.

warn never reaches Sentry: LogService.warn() only calls addBreadcrumb (shared/src/utils/general/log/service.ts:163-167), and a breadcrumb is transmitted solely when some later error event fires. So the moment autoplay died was invisible unless something unrelated broke afterwards and happened to carry the crumb along.

Change

Raised to errorLog, and the message now states the consequence — Replenish retry failed — autoplay stopped for this guild — rather than just naming the failed call. Drops the warnLog import this left unused.

Not restructuring the retry itself. The issue floated awaiting it or adding a user-visible notice; both change behaviour (the retry is intentionally detached from the track-start path, and an in-channel notice needs a product decision about noise). Making the failure visible is the part that was unambiguously missing.

Full bot suite: 3154 passed, 1 skipped. Typecheck and lint clean.


Related: #1996 does not reproduce

While here I checked #1996, which claims void runSafelyAsync(...) at errorHandlers.ts:186-189 silently swallows recovery exceptions. It does not:

runSafelyAsync  (errorHandlers.ts:129-139)
  └─ logHandlerFailure  (:113-119)
       └─ safeErrorLog  (:78-88)
            └─ errorLog   ← reaches Sentry

The catch already logs at error level with the message Player error event handler failed:, which is exactly what that issue asks for ("logs at error level (not silently)... so a failed recovery is distinguishable from a successful one"). Commenting there separately rather than folding a no-op change into this PR.


Summary by cubic

Reports the second consecutive autoplay replenish failure at error level so Sentry captures the event and we know autoplay stopped for the guild. Previously this logged a warning only, which added a breadcrumb sent only if a later error occurred.

  • Logs with errorLog (from @lucky/shared/utils) and a clearer message: “Replenish retry failed — autoplay stopped for this guild,” including guildId.
  • Keeps retry behavior unchanged (first failure schedules a retry after 5s; after the second failure, no more retries).
  • Removes the unused warnLog import.

Written for commit 9457778. Summary will update on new commits.

Review in cubic

When the first replenish fails, a retry is scheduled 5s later. If that
retry also fails, autoplay has stopped for the guild and nothing will
try again — but it was only warn-logged.

warn never reaches Sentry: LogService.warn only adds a breadcrumb, and a
breadcrumb is transmitted solely when some later error event fires. So
the moment autoplay died was invisible unless something unrelated broke
afterwards and happened to carry the crumb along.

Raised to errorLog and the message now says what actually happened
rather than naming the failed call.

Drops the warnLog import, which this left unused.

Closes #1995.
@coderabbitai

coderabbitai Bot commented Aug 21, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

@LucasSantana-Dev, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 22 minutes

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: dc81bc80-2f22-4cfc-961c-6bd281b34221

📥 Commits

Reviewing files that changed from the base of the PR and between 9baedf4 and 9457778.

📒 Files selected for processing (1)
  • packages/bot/src/handlers/player/trackHandlers.ts

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


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.

@github-actions

Copy link
Copy Markdown

Failed to generate code suggestions for PR

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Graphify reviewed this change.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).


Graphify review — findings

Promotes the second-consecutive replenish-retry failure in handleQueueReplenishment from warnLog to errorLog so the moment autoplay dies for a guild is actually reported to Sentry (#1995). Drops the now-unused warnLog import.

No blocking issues surfaced.

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 31 functions depend on the 25 functions this change touches.

Health — this change adds coupling hotspots:

  • new: setupTrackHandlers() — 4 callers, 6 callees
  • new: handlePlayerSkip() — 2 callers, 11 callees
  • new: handlePlayerStart() — 2 callers, 10 callees
  • new: handlePlayerFinish() — 2 callers, 8 callees
  • new: replenishIfAutoplay() — 3 callers, 4 callees

Verification — 31 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 29 function(s) in the blast radius were not formally verified this run

· 5 more finding(s) on lines outside this diff (see the check run).

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 1 file

Auto-approved: Upgrades logging from warning to error for final autoplay replenishment failures to ensure they are reported to Sentry. This change improves observability without altering the underlying retry logic.

Re-trigger cubic

@sonarqubecloud

Copy link
Copy Markdown

@LucasSantana-Dev
LucasSantana-Dev merged commit 2c5962e into main Aug 21, 2026
45 checks passed
@LucasSantana-Dev
LucasSantana-Dev deleted the fix/player-recovery-observability branch August 21, 2026 19:02

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Graphify reviewed this change.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).


Graphify review — findings

Promotes the replenish-retry failure log in handleQueueReplenishment from warnLog to errorLog, since a second consecutive failure means autoplay has stopped for the guild and won't retry. Drops the now-unused warnLog import.

No blocking issues surfaced.

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 31 functions depend on the 25 functions this change touches.

Health — this change adds coupling hotspots:

  • new: setupTrackHandlers() — 4 callers, 6 callees
  • new: handlePlayerSkip() — 2 callers, 11 callees
  • new: handlePlayerStart() — 2 callers, 10 callees
  • new: handlePlayerFinish() — 2 callers, 8 callees
  • new: replenishIfAutoplay() — 3 callers, 4 callees

Verification — 31 functions in the blast radius were not formally verified this run (proofs are advisory here).

Health delta baseline: last indexed commit 2c5962e (diverged from this PR's base — delta is approximate).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 29 function(s) in the blast radius were not formally verified this run

· 5 more finding(s) on lines outside this diff (see the check run).

LucasSantana-Dev added a commit that referenced this pull request Aug 22, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>2.39.6</summary>

##
[2.39.6](v2.39.5...v2.39.6)
(2026-08-22)


### Bug Fixes

* **bot:** drop the audio-features scoring path, spotify returns 403
([#2074](#2074))
([11891bf](11891bf))
* **bot:** drop the autoplay arm that calls a removed spotify endpoint
([#2071](#2071))
([682a795](682a795))
* **bot:** fall back past a dead spotify arm in /artist
([#2052](#2052))
([45dc998](45dc998))
* **bot:** make three silent /play failures observable
([#2062](#2062))
([e6b2810](e6b2810))
* **bot:** pick closest-duration soundcloud fallback match
([#2049](#2049))
([738efb8](738efb8))
* **bot:** report a dead autoplay replenish at error level
([#2063](#2063))
([2c5962e](2c5962e))
* **bot:** report spotify extractor health instead of failing silently
([#2060](#2060))
([ddaa287](ddaa287))
* **bot:** rerank search results toward exact artist/title match
([#2045](#2045))
([0c719d5](0c719d5))
* **bot:** resolve /album text queries to an album url
([#2053](#2053))
([4498299](4498299))
* **bot:** restore youtube-dl-exec, discord-player-youtubei needs it
undeclared
([#2040](#2040))
([c75475b](c75475b))
* **bot:** stop reporting an outage when the fallbacks found nothing
([#2069](#2069))
([37412e2](37412e2))
* **bot:** surface dead last.fm env session key to sentry
([#2047](#2047))
([3c97291](3c97291))
* **bot:** update a case reason through the service layer
([#2066](#2066))
([187d783](187d783))
* **bot:** use metadata setter instead of direct property assignment
([#2042](#2042))
([740d53e](740d53e))


### Performance Improvements

* **bot:** cut yt-dlp timeout from 15s to 6s
([#2044](#2044))
([39e9e3c](39e9e3c))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
This was referenced Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(bot): autoplay replenish retry failure is unawaited and silently logged

1 participant