Surface track playback errors to users and support yt-dlp JS runtimes#53
Open
Firestone82 wants to merge 4 commits into
Open
Surface track playback errors to users and support yt-dlp JS runtimes#53Firestone82 wants to merge 4 commits into
Firestone82 wants to merge 4 commits into
Conversation
Hosts where yt-dlp's bundled JS interpreter can't decipher YouTube signatures need an external runtime (Deno/Node) via --js-runtimes. The new YT_DLP_JS_RUNTIMES env var is appended to the download, probe, playlist-scrape, and streaming YoutubeDl input so the workaround applies everywhere yt-dlp runs. See https://github.com/yt-dlp/yt-dlp/wiki/EJS#deno
Track errors now reach the text channel: `ErrorHandler` carries the serenity context, the player, and the guild channel so it can read the current track and post a `PlaybackErrorEmbed` with the underlying PlayError (e.g. yt-dlp signature/extraction failure). Songbird still fires TrackEvent::End after the error, so QueueHandler keeps the queue advancing — we only add the user-facing notice here. The 5-minute inactivity timer (queue_handler + cmd_stop) used to fire unconditionally, including after the bot had already been kicked or dragged out of voice. It now checks `channel_service::bot_in_voice` before announcing the leave, so a vacated bot doesn't post "leaving voice channel" from a channel it isn't in anymore.
The 5-minute inactivity leave used to land in whatever text channel issued the first !play, which gets noisy when the music conversation has moved on. Route it through the bot's current voice channel instead — Discord voice channels have an integrated text chat on the same ChannelId, so messages there sit next to the voice activity they describe. Adds `channel_service::bot_voice_channel` (looks up the bot's current voice channel via cache) and a `send_channel_id` variant on the SendEmbed trait so we can post to a raw ChannelId without first resolving a GuildChannel. The kicked/dragged-out check from the previous commit folds into the same lookup — `None` already means "not in voice", so the timer bails for free.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6de85320a3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
`manager.join` is idempotent — `!play` calls it on every invocation even when the bot is already connected, and songbird stacks global event listeners on the same Call. With the previous unit-struct ErrorHandler that just logged, this produced duplicate log lines; now that the handler posts an embed, every prior `!play` would contribute another duplicate PlaybackErrorEmbed on a single failure. Check `manager.get(guild_id)` before joining and only register the handler on the first connect.
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.
Summary
This PR improves error visibility and adds support for external JavaScript runtimes in yt-dlp. When a track fails to play, users now see a descriptive error message in the voice channel's text chat instead of the track silently skipping. Additionally, the bot can now forward a
YT_DLP_JS_RUNTIMESenvironment variable to all yt-dlp invocations, enabling hosts to use native JS engines (Deno, Node) when the bundled interpreter struggles with YouTube signature extraction.Key Changes
Error Handler Enhancement:
ErrorHandlernow captures playback error details from Songbird'sEventContext, extracts the track title from the player state, and sends a formattedPlaybackErrorEmbedto the voice channel's integrated text chat. This surfaces why tracks were skipped (typically yt-dlp signature/extraction failures) to users.Channel Service Utilities: Added
bot_in_voice()andbot_voice_channel()helpers to safely determine the bot's current voice channel without relying on stale cachedGuildChannelreferences. This prevents announcing leaves that already happened when the bot was kicked or dragged out of voice.Embed Service Extension: Added
send_channel_id()method to theSendEmbedtrait and a correspondingsend_channel_id_embed()function to support sending embeds to channels identified by rawChannelIdrather than cachedGuildChannelobjects. This is necessary for writing into voice channel text chats looked up through the bot's voice state.yt-dlp JS Runtime Support: Created
utils/yt_dlp_utils.rswith anextra_args()function that reads theYT_DLP_JS_RUNTIMESenvironment variable and returns--js-runtimes <value>CLI arguments. Integrated this into all yt-dlp invocations:cache_service::cache_track(),cache_service::probe_track(),Track::get_input(), andYoutubeClient::fetch_playlist().Inactivity Leave Notices: Updated
cmd_stop.rsandqueue_handler.rsto usebot_voice_channel()instead of relying on potentially staleguild_channelreferences, ensuring inactivity leave notices are only sent when the bot is actually still in voice.Documentation: Updated
.env.examplewith guidance on the newYT_DLP_JS_RUNTIMESconfiguration option and linked to the yt-dlp wiki for context.Implementation Details
EventContext::Trackto find thePlayMode::Erroredstate and convert it to a user-friendly string.ErrorHandleris now instantiated withserenity_ctx,player, andguild_channelat event registration time inchannel_service::join_user_channel(), allowing it to send embeds and read current track metadata.https://claude.ai/code/session_013G7EXeh6SyhGywqvugD1t9