From f0337050c14592c5d43e8ae574ab0ca47ea2cb93 Mon Sep 17 00:00:00 2001 From: Johannes Heuel Date: Fri, 9 Aug 2024 11:53:49 +0200 Subject: [PATCH] add error context --- src/commands/join.rs | 7 +-- src/commands/play.rs | 105 +++++++++++++++++++++++++++---------------- 2 files changed, 71 insertions(+), 41 deletions(-) diff --git a/src/commands/join.rs b/src/commands/join.rs index efa2148..2a44c78 100644 --- a/src/commands/join.rs +++ b/src/commands/join.rs @@ -1,4 +1,5 @@ use crate::state::State; +use anyhow::Context; use std::error::Error; use tracing::debug; use twilight_model::{ @@ -22,7 +23,7 @@ pub(crate) async fn join_channel( let channel_id = state .cache .voice_state(user_id, guild_id) - .ok_or("Cannot get voice state for user")? + .context("Could not get voice state for user")? .channel_id(); // join the voice channel @@ -30,12 +31,12 @@ pub(crate) async fn join_channel( .songbird .join(guild_id.cast(), channel_id) .await - .map_err(|e| format!("Could not join voice channel: {:?}", e))?; + .context("Could not join voice channel")?; // signal that we are not listening if let Some(call_lock) = state.songbird.get(guild_id.cast()) { let mut call = call_lock.lock().await; - call.deafen(true).await?; + call.deafen(true).await.context("Could not deafen")?; } // create guild config diff --git a/src/commands/play.rs b/src/commands/play.rs index 5622072..1860222 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -25,6 +25,7 @@ use twilight_util::builder::embed::EmbedBuilder; use twilight_util::builder::InteractionResponseDataBuilder; use url::Url; +#[derive(Debug)] struct TrackType { url: String, title: Option, @@ -245,6 +246,7 @@ pub(crate) async fn play( Err(e) => { tracing::debug!("Search did not result in any tracks: {}", e); let content = "Search did not result in any tracks.".to_string(); + let embeds = vec![EmbedBuilder::new() .description(content) .color(colors::RED) @@ -334,12 +336,13 @@ pub(crate) async fn play_inner( .interaction(interaction.application_id) .update_response(&interaction.token) .embeds(Some(&embeds))? - .await?; + .await + .context("Could not send playlist loading message")?; } if let Some(call_lock) = state.songbird.get(guild_id) { let call = call_lock.lock().await; - call.queue().resume()?; + call.queue().resume().context("Could not resume playing")?; } let mut tracks_added = vec![]; @@ -349,58 +352,84 @@ pub(crate) async fn play_inner( .original_url .clone() .or(yttrack.url.clone()) - .ok_or("Could not find url")?; + .context("Could not find url")?; let mut src = YoutubeDl::new(state.client.clone(), url.clone()); let track: Track = src.clone().into(); - if let Ok(metadata) = src.aux_metadata().await { - debug!("metadata: {:?}", metadata); + match src.aux_metadata().await { + Ok(metadata) => { + debug!("metadata: {:?}", metadata); - persistence(interaction, yttrack, Arc::clone(&state)) - .await - .unwrap_or_else(|e| { - tracing::error!("could not persist track: {:?}", e); + persistence(interaction, yttrack, Arc::clone(&state)) + .await + .unwrap_or_else(|e| { + tracing::error!("could not persist track: {:?}", e); + }); + + tracks_added.push(TrackType { + url: url.clone(), + title: metadata.title.clone(), + duration_string: yttrack.duration_string.clone(), + channel: yttrack.channel.clone(), + thumbnail: metadata.thumbnail.clone(), }); - tracks_added.push(TrackType { - url: url.clone(), - title: metadata.title.clone(), - duration_string: yttrack.duration_string.clone(), - channel: yttrack.channel.clone(), - thumbnail: metadata.thumbnail.clone(), - }); - - if let Some(call_lock) = state.songbird.get(guild_id) { - let mut call = call_lock.lock().await; - let handle = call.enqueue_with_preload( - track, - metadata.duration.map(|duration| -> Duration { - if duration.as_secs() > 5 { - duration.sub(Duration::from_secs(5)) - } else { - duration - } - }), - ); - let mut x = handle.typemap().write().await; - x.insert::(Metadata { - title: metadata.title, - duration: metadata.duration, - url, - src, - }); + match state.songbird.get(guild_id) { + Some(call_lock) => { + let mut call = call_lock.lock().await; + let handle = call.enqueue_with_preload( + track, + metadata.duration.map(|duration| -> Duration { + if duration.as_secs() > 5 { + duration.sub(Duration::from_secs(5)) + } else { + duration + } + }), + ); + let mut x = handle.typemap().write().await; + x.insert::(Metadata { + title: metadata.title, + duration: metadata.duration, + url, + src, + }); + } + None => tracing::error!("could not get call lock"), + } + } + Err(e) => { + tracing::error!("could not get metadata: {:?}", e); + if e.to_string() + .contains("Sign in to confirm you’re not a bot.") + { + let content = + "I seem to have been flagged by YouTube as a bot. :-(".to_string(); + let embeds = vec![EmbedBuilder::new() + .description(content) + .color(colors::RED) + .build()]; + state + .http + .interaction(interaction.application_id) + .update_response(&interaction.token) + .embeds(Some(&embeds))? + .await?; + return Ok(()); + } } } } - let embeds = build_embeds(&tracks, &tracks_added); + let embeds = build_embeds(&tracks, &tracks_added); state .http .interaction(interaction.application_id) .update_response(&interaction.token) .embeds(Some(&embeds))? - .await?; + .await + .context("Could not send final play message")?; Ok(()) }