diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index c5e1cad..89a18de 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -2,5 +2,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/commands/accountv2.rs b/src/commands/accountv2.rs
index db6ab86..8596cae 100644
--- a/src/commands/accountv2.rs
+++ b/src/commands/accountv2.rs
@@ -15,7 +15,8 @@ use serenity::{
};
use sqlx::{Pool, query_as, Sqlite};
-use crate::{Context, Error};
+use crate::Context;
+use crate::error::Error;
#[derive(Deserialize)]
struct Links {
@@ -53,7 +54,12 @@ impl Uuid {
async fn fetch(ign: &str) -> Result {
let url: String = format!("https://api.mojang.com/users/profiles/minecraft/{ign}");
let response: Response = reqwest::get(url).await?;
- match response.error_for_status() {
+ let response_text = response.error_for_status()?.text().await.unwrap();
+ let uuid = (serde_json::from_str(response_text.as_str())
+ as Result)
+ .map(|mojang_player: MojangPlayer| Uuid { uuid: mojang_player.id })?;
+ Ok(uuid)
+ /*match response.error_for_status() {
Ok(res) => {
let response_text = res.text().await.unwrap();
let uuid = (serde_json::from_str(response_text.as_str())
@@ -64,7 +70,7 @@ impl Uuid {
Err(why) => Err(Error::from(format!(
"Mojang returned an error. Please make sure to enter a valid Minecraft username.\n\n\
Details: {}", why).as_str())),
- }
+ }*/
}
}
#[derive(PartialEq)]
@@ -75,19 +81,11 @@ impl DiscordId {
async fn matches_fetch(user: &User, uuid: &str, client: &Client) -> Result {
let url: String = format!("https://api.hypixel.net/v2/player?uuid={}", uuid);
let response: Response = client.get(url).send().await?;
- match response.error_for_status() {
- Ok(res) => {
- let response_text = res.text().await.unwrap();
- let matches = (serde_json::from_str(response_text.as_str())
- as Result)
- .map(|hypixel_response: HypixelResponse| user.name == hypixel_response.player.social_media.links.discord)?;
- Ok(matches)
- }
- Err(why) => {
- println!("Hypixel issue: {}", why);
- Err(Error::from("Hypixel returned an error."))
- }
- }
+ let response_text = response.error_for_status()?.text().await.unwrap();
+ let matches = (serde_json::from_str(response_text.as_str())
+ as Result)
+ .map(|hypixel_response: HypixelResponse| user.name == hypixel_response.player.social_media.links.discord)?;
+ Ok(matches)
}
}
impl<'a, R: sqlx::Row> sqlx::FromRow<'a, R> for DiscordId
@@ -116,17 +114,17 @@ impl Link {
minecraft_accounts: vec![],
}
}
- async fn minecraft(mut self, pool: &Pool) -> Self {
+ async fn minecraft(mut self, pool: &Pool) -> Result {
let link_id: i16 = self.link_id.cast_signed();
self.minecraft_accounts = query_as(format!("SELECT minecraft_uuid AS uuid FROM minecraft_links WHERE link_id = {link_id};").as_str())
- .fetch_all(pool).await.expect("Error getting Minecraft UUIDs.");
- self
+ .fetch_all(pool).await?;
+ Ok(self)
}
- async fn discord(mut self, pool: &Pool) -> Self {
+ async fn discord(mut self, pool: &Pool) -> Result {
let link_id: i16 = self.link_id.cast_signed();
self.discord_ids = query_as(format!("SELECT discord_id FROM discord_links WHERE link_id = {link_id};").as_str())
- .fetch_all(pool).await.expect("Error getting Discord IDs.");
- self
+ .fetch_all(pool).await?;
+ Ok(self)
}
}
#[poise::command(slash_command, subcommands("add", "list"))]
@@ -148,26 +146,23 @@ pub(crate) async fn add<'a>(
ctx.defer_ephemeral().await?;
let user = user.unwrap_or(ctx.author().clone());
let uuid = Uuid::fetch(ign.as_str()).await?;
- let valid = DiscordId::matches_fetch(&user, uuid.get(), &ctx.data().hypixel_api_client).await
- .expect("This Minecraft account does not have a Discord account linked.");
- match valid {
+ match DiscordId::matches_fetch(&user, uuid.get(), &ctx.data().hypixel_api_client).await? {
true => {
- let r = CreateReply::default().ephemeral(false);
let pool: Pool = ctx.data().sqlite_pool.clone();
let (status, link_id) = match link_id_from_minecraft(&pool, uuid.get()).await {
None => {
match link_id_from_discord(&pool, user.id.get()).await {
None => {
- let id = new_link_id(&pool).await;
+ let id = new_link_id(&pool).await?;
sqlx::query(format!("INSERT INTO discord_links VALUES ({}, {});", id.cast_signed(), user.id.get()).as_str())
- .execute(&pool).await.expect("Database Error: inserting new minecraft value");
+ .execute(&pool).await?;
sqlx::query(format!("INSERT INTO minecraft_links VALUES ({}, \"{}\");", id.cast_signed(), uuid.get()).as_str())
- .execute(&pool).await.expect("Database Error: inserting new minecraft value");
+ .execute(&pool).await?;
("Linked your Discord and Minecraft account.", id)
}
Some(dc_id) => {
sqlx::query(format!("INSERT INTO minecraft_links VALUES ({}, \"{}\");", dc_id.cast_signed(), uuid.get()).as_str())
- .execute(&pool).await.expect("Database Error: inserting new minecraft value");
+ .execute(&pool).await?;
("Your Discord account has previously had an account linked. Added the new link.", dc_id)
}
}
@@ -176,22 +171,21 @@ pub(crate) async fn add<'a>(
match link_id_from_discord(&pool, user.id.get()).await {
None => {
sqlx::query(format!("INSERT INTO discord_links VALUES ({}, {});", mc_id.cast_signed(), user.id.get()).as_str())
- .execute(&pool).await.expect("Database Error: inserting new minecraft value");
+ .execute(&pool).await?;
("Your Minecraft account has previously had an account linked. Added the new link.", mc_id)
}
Some(dc_id) => {
sqlx::query(format!("UPDATE minecraft_links SET link_id = {} WHERE link_id = {};", mc_id.cast_signed(), dc_id.cast_signed()).as_str())
- .execute(&pool).await.expect("Database Error: Merging Minecraft Accounts.");
+ .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())
- .execute(&pool).await.expect("Database Error: Merging Discord Accounts.");
+ .execute(&pool).await?;
("Both your Discord and Minecraft account had linked accounts. Merged all account links.", mc_id)
}
}
}
};
- ctx.send(r.content(status)).await?;
- let link = Link::new(link_id).minecraft(&pool).await.discord(&pool).await;
- let s = list_string(link, user.id.get()).await;
+ let link = Link::new(link_id).minecraft(&pool).await?.discord(&pool).await?;
+ let s = list_string(link, user.id.get());
ChannelId::new(1257776992497959075).send_message(
ctx,
CreateMessage::new()
@@ -202,15 +196,14 @@ pub(crate) async fn add<'a>(
CreateButton::new("deny_verification").emoji(ReactionType::from('❌')),
])]),
).await?;
- }
+ ctx.send(CreateReply::default().ephemeral(false).content(status)).await?;
+ Ok(())
+ },
false => {
- let r = CreateReply::default().ephemeral(true)
- .content(format!("The Discord account linked on Hypixel does not seem to match the specified account.\n\
- Expected account link: `{}`", user.name));
- ctx.send(r).await?;
+ Err(Error::Other(format!("The Discord account linked on Hypixel does not match the specified discord account.\n\
+ Please set your linked Discord account on Hypixel to `{}`.", user.name)))
}
}
- Ok(())
}
#[poise::command(slash_command)]
@@ -223,18 +216,18 @@ pub(crate) async fn list(
let r = CreateReply::default().ephemeral(false);
let pool: Pool = ctx.data().sqlite_pool.clone();
let link_id = link_id_from_discord(&pool, user.id.get()).await.expect("This user has no linked accounts");
- let link = Link::new(link_id).minecraft(&pool).await.discord(&pool).await;
- let s = list_string(link, user.id.get()).await;
+ let link = Link::new(link_id).minecraft(&pool).await?.discord(&pool).await?;
+ let s = list_string(link, user.id.get());
ctx.send(r.content(s).allowed_mentions(CreateAllowedMentions::new().empty_roles().empty_users())).await?;
Ok(())
}
#[poise::command(slash_command)]
pub(crate) async fn remove(_ctx: Context<'_>) -> Result<(), Error> {
- unreachable!()
+ unimplemented!()
}
-async fn list_string(link: Link, user_id: u64) -> String {
+fn list_string(link: Link, user_id: u64) -> String {
let mut discord_list = String::from("### Discord:");
for dc in link.discord_ids {
discord_list.push_str(format!("\n- <@{}>", dc.id).as_str());
@@ -247,26 +240,16 @@ async fn list_string(link: Link, user_id: u64) -> String {
}
async fn link_id_from_minecraft(pool: &Pool, minecraft_uuid: &str) -> Option {
- return query_as(
- format!(
- "SELECT link_id FROM minecraft_links WHERE minecraft_uuid = \"{minecraft_uuid}\" LIMIT 1;"
- )
- .as_str(),
- )
+ query_as(format!("SELECT link_id FROM minecraft_links WHERE minecraft_uuid = \"{minecraft_uuid}\" LIMIT 1;").as_str())
.fetch_optional(pool)
- .await
- .expect("Database error: fetching link id by uuid")
- .map(|link_id: LinkId| link_id.link_id.cast_unsigned());
+ .await.expect("Database error: fetching link id by uuid")
+ .map(|link_id: LinkId| link_id.link_id.cast_unsigned())
}
async fn link_id_from_discord(pool: &Pool, snowflake: u64) -> Option {
- let discord_id: i64 = snowflake.cast_signed();
- return query_as(
- format!("SELECT link_id FROM discord_links WHERE discord_id = {discord_id} LIMIT 1;").as_str(),
- )
+ query_as(format!("SELECT link_id FROM discord_links WHERE discord_id = {} LIMIT 1;", snowflake.cast_signed()).as_str())
.fetch_optional(pool)
- .await
- .expect("Database error: fetching link id by discord")
- .map(|link_id: LinkId| link_id.link_id.cast_unsigned());
+ .await.expect("Database error: fetching link id by discord")
+ .map(|link_id: LinkId| link_id.link_id.cast_unsigned())
}
#[derive(sqlx::FromRow)]
@@ -274,11 +257,9 @@ struct LinkId {
link_id: i16,
}
-async fn new_link_id(pool: &Pool) -> u16 {
- let result: Result = query_as("SELECT MAX(link_id) AS link_id FROM minecraft_links;")
+async fn new_link_id(pool: &Pool) -> Result {
+ let result: LinkId = query_as("SELECT MAX(link_id) AS link_id FROM minecraft_links;")
.fetch_one(pool)
- .await;
- result
- .expect("Database error: fetching new id")
- .link_id.cast_unsigned() + 1
+ .await?;
+ Ok(result.link_id.cast_unsigned() + 1)
}
\ No newline at end of file
diff --git a/src/commands/bots.rs b/src/commands/bots.rs
index 6b34203..d6ee489 100644
--- a/src/commands/bots.rs
+++ b/src/commands/bots.rs
@@ -1,7 +1,7 @@
use std::string::String;
-
-use crate::{Context, Error};
-use crate::commands::command_helper;
+use poise::CreateReply;
+use crate::Context;
+use crate::error::Error;
#[poise::command(slash_command, guild_only, owners_only)]
pub(crate) async fn bots(
@@ -12,6 +12,7 @@ pub(crate) async fn bots(
) -> Result<(), Error> {
ctx.defer_ephemeral().await?;
*ctx.data().bots.write().await = bots;
- let reply = format!("{} bots are now registered as available", bots).to_string();
- command_helper::send_simple(ctx, reply).await
+ let content = format!("{} bots are now registered as available", bots).to_string();
+ ctx.send(CreateReply::default().content(content).ephemeral(true)).await?;
+ Ok(())
}
diff --git a/src/commands/command_helper.rs b/src/commands/command_helper.rs
index 6ec34c8..adf37ce 100644
--- a/src/commands/command_helper.rs
+++ b/src/commands/command_helper.rs
@@ -1,25 +1,7 @@
use std::time::Duration;
-use crate::{Context, Error};
-
-pub(crate) async fn send_simple(ctx: Context<'_>, reply: String) -> Result<(), Error> {
- if let Err(why) = ctx
- .send(poise::CreateReply {
- content: Some(reply),
- embeds: vec![],
- attachments: vec![],
- ephemeral: Some(true),
- components: None,
- allowed_mentions: None,
- reply: false,
- __non_exhaustive: (),
- })
- .await
- {
- println!("Error sending message: {:?}", why)
- }
- Ok(())
-}
+use crate::Context;
+use crate::error::Error;
pub(crate) fn cooldown(ctx: &Context, user: u64, guild: u64) -> Result<(), Error> {
let mut cooldown_tracker = ctx.command().cooldowns.lock().unwrap();
@@ -35,7 +17,7 @@ pub(crate) fn cooldown(ctx: &Context, user: u64, guild: u64) -> Result<(), Error
Ok(())
} else {
match cooldown_tracker.remaining_cooldown((*ctx).cooldown_context(), &cooldown_durations) {
- Some(remaining) => Err(format!("Please wait {} seconds", remaining.as_secs()).into()),
+ Some(remaining) => Err(Error::OnCooldown(remaining)),
None => Ok(cooldown_tracker.start_cooldown((*ctx).cooldown_context())),
}
}
diff --git a/src/commands/helpstart.rs b/src/commands/helpstart.rs
index c390ffa..b0d06b1 100644
--- a/src/commands/helpstart.rs
+++ b/src/commands/helpstart.rs
@@ -1,8 +1,9 @@
use poise::CreateReply;
use serenity::all::CreateAllowedMentions;
-use crate::{Context, Error};
+use crate::Context;
use crate::commands::command_helper;
+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 7daf9e6..11ab79e 100644
--- a/src/commands/lfg.rs
+++ b/src/commands/lfg.rs
@@ -1,13 +1,14 @@
use poise::{ChoiceParameter, CreateReply};
use serenity::all::{CreateAllowedMentions, RoleId};
-use crate::{Context, Error};
+use crate::Context;
//from main.rs
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;
#[derive(Debug, poise::ChoiceParameter, PartialEq)]
pub enum Map {
diff --git a/src/commands/xd.rs b/src/commands/xd.rs
index e7d191a..19c03a0 100644
--- a/src/commands/xd.rs
+++ b/src/commands/xd.rs
@@ -1,4 +1,5 @@
-use crate::{Context, Error};
+use crate::Context;
+use crate::error::Error;
const XD: &str = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⡿⠿⠿⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⡿⠿⠿⠿⠿⠿⠿⠿⢿⡿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣧⣄⡀⠀⠀⠀⢀⣠⣼⣿⣿⣿⣿⣧⣄⡀⠀⠀⠀⣀⣤⣼⣷⣦⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⢿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠻⣿⣿⣿⣿⣿⣿⠟⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣶⣦⣄⡀⠀⠀⠙⢿⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠙⣿⣿⣿⣿⠋⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⠈⢿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⠈⢿⡿⠁⠀⠀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⢸⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡗⠀⠀⠀⠐⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀⠀⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⠀⣠⡀⠀⠀⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀⠀⣰⣿⣷⡄⠀⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⠀⣾⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⡟⠁⠀⢀⣼⣿⣿⣿⣿⣆⠀⠀⠈⠻⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⢀⣼⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⠋⠀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠙⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⠿⠛⠁⠀⠀⣠⣾⣿⣿⣿⣿⣿\n⣿⣿⣿⠿⠛⠁⠀⠀⠀⠙⠻⣿⣿⣿⣿⣿⡿⠟⠋⠀⠀⠀⠈⠛⠻⡿⠟⠛⠁⠀⠀⠈⠉⠉⠉⠉⠀⠀⠀⠀⣀⣴⣾⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣿⣿⣿⣿⣿⣷⣶⣶⣶⣶⣶⣶⣶⣶⣷⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n";
diff --git a/src/error.rs b/src/error.rs
new file mode 100644
index 0000000..57b8d6f
--- /dev/null
+++ b/src/error.rs
@@ -0,0 +1,46 @@
+#[derive(Debug)]
+pub enum Error {
+ SqlxError(sqlx::Error),
+ HttpsError(reqwest::Error),
+ ParsingError(serde_json::Error),
+ SerenityError(serenity::Error),
+ OnCooldown(std::time::Duration),
+ Other(String)
+}
+
+impl std::fmt::Display for Error {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ match self {
+ 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::OnCooldown(d) => write!(f, "This command is on cooldown. {}s remaining.", d.as_secs()),
+ Error::Other(s) => write!(f, "{}", s),
+ }
+ }
+}
+
+impl From for Error {
+ fn from(error: sqlx::Error) -> Self {
+ Error::SqlxError(error)
+ }
+}
+
+impl From for Error {
+ fn from(error: reqwest::Error) -> Self {
+ Error::HttpsError(error)
+ }
+}
+
+impl From for Error {
+ fn from(error: serde_json::Error) -> Self {
+ Error::ParsingError(error)
+ }
+}
+
+impl From for Error {
+ fn from(error: serenity::Error) -> Self {
+ Error::SerenityError(error)
+ }
+}
\ No newline at end of file
diff --git a/src/handlers/bot_interaction.rs b/src/handlers/bot_interaction.rs
index ffb36d2..227a01b 100644
--- a/src/handlers/bot_interaction.rs
+++ b/src/handlers/bot_interaction.rs
@@ -1,6 +1,6 @@
use serenity::all::{ComponentInteraction, ComponentInteractionDataKind, Context, CreateMessage, EditMessage, GuildId, Interaction, RoleId};
-use crate::Error;
+use crate::error::Error;
pub(crate) async fn component(ctx: &Context, interaction: &Interaction) -> Result<(), Error> {
let component = interaction.clone().message_component().unwrap();
diff --git a/src/handlers/message.rs b/src/handlers/message.rs
index 881e2b2..b302db4 100644
--- a/src/handlers/message.rs
+++ b/src/handlers/message.rs
@@ -1,6 +1,6 @@
use serenity::all::{Context, Message};
-use crate::Error;
+use crate::error::Error;
pub(crate) async fn on_create(ctx: &Context, msg: &Message) -> Result<(), Error> {
match msg.guild_id.map(|g| g.get()) {
diff --git a/src/handlers/thread.rs b/src/handlers/thread.rs
index ebb57d8..bb8a053 100644
--- a/src/handlers/thread.rs
+++ b/src/handlers/thread.rs
@@ -1,7 +1,7 @@
use serenity::all::{Context, GuildChannel};
use serenity::builder::EditThread;
-use crate::Error;
+use crate::error::Error;
pub(crate) async fn on_create(ctx: &Context, thread: &GuildChannel) -> Result<(), Error> {
match thread.parent_id.map(|parent| parent.get()) {
diff --git a/src/main.rs b/src/main.rs
index 78ac607..745e44b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,22 +5,25 @@ use std::convert::Into;
use std::sync::Arc;
use std::time::Duration;
-use poise::serenity_prelude as serenity;
+use poise::{CreateReply, FrameworkError, serenity_prelude as serenity};
use serenity::{FullEvent, model::id::UserId};
use serenity::all::{ActivityData, InteractionType, RoleId};
use serenity::prelude::GatewayIntents;
use sqlx::Sqlite;
use tokio::sync::RwLock;
+use error::Error;
mod commands;
mod handlers;
+mod error;
struct Data {
bots: Arc>,
sqlite_pool: sqlx::Pool,
hypixel_api_client: reqwest::Client,
} // User data, which is stored and accessible in all command invocations
-type Error = Box;
+
+
type Context<'a> = poise::Context<'a, Data, Error>;
#[tokio::main]
async fn main() {
@@ -59,7 +62,18 @@ async fn main() {
on_error: |error| {
Box::pin(async move {
match error {
- other => poise::builtins::on_error(other).await.unwrap(),
+ 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);
+ }
+ }
}
})
},