diff --git a/src/commands/accountv2.rs b/src/commands/accountv2.rs index f84b5ed..7ec3f25 100644 --- a/src/commands/accountv2.rs +++ b/src/commands/accountv2.rs @@ -6,11 +6,11 @@ use serenity::{ json::JsonError, }; use serenity::all::ButtonStyle; -use sqlx::{query_as, Pool, Sqlite}; +use sqlx::{Pool, query_as, Sqlite}; use crate::commands::command_helper::cooldown; -use crate::error::Error; use crate::Context; +use crate::error::Error; #[derive(Deserialize)] struct Links { @@ -145,7 +145,7 @@ pub(crate) async fn add<'a>( #[max_length = 16] ign: String, #[description = "Discord User"] user: Option, - #[description = "Minecraft username"] force: Option, + #[description = "admin-only"] force: Option, ) -> Result<(), Error> { ctx.defer_ephemeral().await?; let user: User = user.unwrap_or(ctx.author().clone()); @@ -187,20 +187,20 @@ pub(crate) async fn add<'a>( mc_id.cast_signed(), dc_id.cast_signed() ) - .as_str(), + .as_str(), ) - .execute(&pool) - .await?; + .execute(&pool) + .await?; sqlx::query( format!( "UPDATE discord_links SET link_id = {} WHERE link_id = {};", mc_id.cast_signed(), dc_id.cast_signed() ) - .as_str(), + .as_str(), ) - .execute(&pool) - .await?; + .execute(&pool) + .await?; "Both your Discord and Minecraft account had linked accounts. Merged all account links." } }, @@ -213,9 +213,15 @@ pub(crate) async fn add<'a>( .content(s) .allowed_mentions(CreateAllowedMentions::new().empty_roles().all_users(true)) .components(vec![CreateActionRow::Buttons(vec![ - CreateButton::new("accept_verification").emoji(ReactionType::from('✅')).style(ButtonStyle::Primary), - CreateButton::new("deny_verification").emoji(ReactionType::from('❌')).style(ButtonStyle::Primary), - CreateButton::new("list_accounts").emoji(ReactionType::from('📜')).style(ButtonStyle::Secondary), + CreateButton::new("accept_verification") + .emoji(ReactionType::from('✅')) + .style(ButtonStyle::Primary), + CreateButton::new("deny_verification") + .emoji(ReactionType::from('❌')) + .style(ButtonStyle::Primary), + CreateButton::new("list_accounts") + .emoji(ReactionType::from('📜')) + .style(ButtonStyle::Secondary), ])]), ) .await?; @@ -242,7 +248,7 @@ pub(crate) async fn list(ctx: Context<'_>, user: Option) -> Result<(), Err r.content(s) .allowed_mentions(CreateAllowedMentions::new().empty_roles().empty_users()), ) - .await?; + .await?; Ok(()) } @@ -285,12 +291,12 @@ async fn link_id_from_discord(pool: &Pool, snowflake: u64) -> Option Result<(), Error> { let mut cooldown_tracker = ctx.command().cooldowns.lock().unwrap(); diff --git a/src/commands/helpstart.rs b/src/commands/helpstart.rs index 44fdb3f..6a53212 100644 --- a/src/commands/helpstart.rs +++ b/src/commands/helpstart.rs @@ -2,8 +2,8 @@ use poise::CreateReply; use serenity::all::CreateAllowedMentions; use crate::commands::command_helper; -use crate::error::Error; use crate::Context; +use crate::error::Error; #[poise::command(slash_command, guild_only)] pub(crate) async fn helpstart( diff --git a/src/commands/lfg.rs b/src/commands/lfg.rs index 39f79e7..6abb3ee 100644 --- a/src/commands/lfg.rs +++ b/src/commands/lfg.rs @@ -7,8 +7,8 @@ use crate::commands::command_helper::cooldown; use crate::commands::lfg::Difficulty::Normal; use crate::commands::lfg::Map::*; use crate::commands::lfg::Mode::*; -use crate::error::Error; use crate::Context; +use crate::error::Error; #[derive(Debug, poise::ChoiceParameter, PartialEq)] pub enum Map { @@ -96,7 +96,7 @@ pub(crate) async fn lfg( AlienArcadium => Normal, }; - let mut reply_content: String = format!("<@&{ping}> {current}/{desired} {map_name}",); + let mut reply_content: String = format!("<@&{ping}> {current}/{desired} {map_name}", ); match difficulty { Normal => {} Difficulty::Hard | Difficulty::Rip => { diff --git a/src/commands/xd.rs b/src/commands/xd.rs index 095cfc3..ad12201 100644 --- a/src/commands/xd.rs +++ b/src/commands/xd.rs @@ -1,5 +1,5 @@ -use crate::error::Error; use crate::Context; +use crate::error::Error; const XD: &str = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⡿⠿⠿⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⡿⠿⠿⠿⠿⠿⠿⠿⢿⡿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\\ n⣿⣿⣿⣧⣄⡀⠀⠀⠀⢀⣠⣼⣿⣿⣿⣿⣧⣄⡀⠀⠀⠀⣀⣤⣼⣷⣦⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⢿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠻⣿⣿⣿⣿⣿⣿⠟⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣶⣦⣄⡀⠀⠀⠙⢿⣿⣿⣿⣿\\ diff --git a/src/error.rs b/src/error.rs index bea832b..1c4d154 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,3 +1,15 @@ +use poise::{CreateReply, FrameworkError}; + +use crate::Data; + +macro_rules! reply_fail_handler { + ($fut:expr) => {{ + if let Err(e) = $fut.await { + tracing::error!("Fatal error while sending error message: {}", e); + } + }}; +} + #[derive(Debug)] pub enum Error { SqlxError(sqlx::Error), @@ -14,7 +26,7 @@ impl std::fmt::Display for Error { Error::SqlxError(e) => write!(f, "SQLx Error: {}", e), Error::HttpsError(e) => write!(f, "HTTPS Error (Hypixel / Mojang API):\n{}", e), Error::ParsingError(e) => write!(f, "Parsing Error:\n {}", e), - Error::SerenityError(e) => write!(f, "Serenity Error:\n {}", e), + Error::SerenityError(e) => write!(f, "Discord Error:\n {}", e), Error::OnCooldown(d) => { write!(f, "This command is on cooldown. {}s remaining.", d.as_secs()) } @@ -46,3 +58,23 @@ impl From for Error { Error::SerenityError(error) } } + +pub(crate) async fn handle_error<'a>(error: FrameworkError<'a, Data, Error>) { + match error { + FrameworkError::Command { error, ctx, .. } => { + reply_fail_handler!(ctx.send(CreateReply::default().content(error.to_string()).ephemeral(true))) + }, + FrameworkError::CommandStructureMismatch { description, ctx, .. } => { + reply_fail_handler!(ctx.send( + CreateReply::default() + .content(format!( + "# Command arguments did not match. The command probably has been updated recently. Try reloading Discord. \ + Description:\n{}", + description + )) + .ephemeral(true) + )) + } + other => reply_fail_handler!(poise::builtins::on_error(other)), + } +} diff --git a/src/handlers/bot_interaction.rs b/src/handlers/bot_interaction.rs index 6ca248c..6aea0df 100644 --- a/src/handlers/bot_interaction.rs +++ b/src/handlers/bot_interaction.rs @@ -1,3 +1,4 @@ +use serenity::all::{ButtonStyle, ComponentInteraction}; use serenity::all::ButtonStyle::Success; use serenity::all::ComponentInteractionDataKind; use serenity::all::Context; @@ -11,10 +12,9 @@ use serenity::all::GuildId; use serenity::all::Interaction; use serenity::all::ReactionType; use serenity::all::RoleId; -use serenity::all::{ButtonStyle, ComponentInteraction}; -use crate::error::Error; use crate::Data; +use crate::error::Error; pub(crate) async fn component(ctx: &Context, interaction: &Interaction, data: &Data) -> Result<(), Error> { let component = interaction.clone().message_component().unwrap(); diff --git a/src/main.rs b/src/main.rs index ffaa475..749c005 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,10 +5,10 @@ use std::convert::Into; use std::sync::Arc; use std::time::Duration; -use poise::{serenity_prelude as serenity, CreateReply, FrameworkError}; +use poise::serenity_prelude as serenity; +use serenity::{FullEvent, model::id::UserId}; use serenity::all::{ActivityData, InteractionType, RoleId}; use serenity::prelude::GatewayIntents; -use serenity::{model::id::UserId, FullEvent}; use sqlx::Sqlite; use tokio::sync::RwLock; @@ -56,25 +56,7 @@ async fn main() { }, on_error: |error| { Box::pin(async move { - match error { - FrameworkError::CommandStructureMismatch { description, ctx, .. } => { - if let Err(e) = ctx - .send(CreateReply::default().content(format!( - "# Command arguments did not match. The command probably has been updated recently. Try reloading \ - Discord. Description:\n{}", - description - ))) - .await - { - tracing::error!("Fatal error while sending error message: {}", e); - } - } - other => { - if let Err(e) = poise::builtins::on_error(other).await { - tracing::error!("Fatal error while sending error message: {}", e); - } - } - } + error::handle_error(error).await; }) }, owners: { HashSet::from([UserId::new(449579075531440128_u64), UserId::new(659112817508745216_u64)]) }, @@ -104,6 +86,7 @@ async fn main() { .await; client.unwrap().start_autosharded().await.unwrap() } + async fn event_handler( ctx: &serenity::Context, event: &FullEvent,