Skip to content

Commit

Permalink
add error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
HadziqM committed Nov 9, 2024
1 parent 3134e5b commit 67f6779
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 15 deletions.
23 changes: 12 additions & 11 deletions common/src/setting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,17 @@ pub struct SettingDiscord {

#[derive(Serialize, Deserialize, Clone)]
pub struct DiscordChannelSetting {
pub log_channel: String,
pub transfer_channel: String,
pub bounty_submision: String,
pub bounty_title: String,
pub speedrun_submision: String,
pub speedrun_leaderboard_channel: String,
pub speedrun_leaderboard_msg: String,
pub market_channel: String,
pub market_menu_channel: String,
pub market_menu_msg: String,
pub log_channel: u64,
pub error_channel: u64,
pub transfer_channel: u64,
pub bounty_submision: u64,
pub bounty_title: u64,
pub speedrun_submision: u64,
pub speedrun_leaderboard_channel: u64,
pub speedrun_leaderboard_msg: u64,
pub market_channel: u64,
pub market_menu_channel: u64,
pub market_menu_msg: u64,
}

#[derive(Serialize, Deserialize, Clone)]
Expand All @@ -147,7 +148,7 @@ pub struct DiscordServerRole {
pub struct DiscordBotSetting {
pub token: String,
pub webhook: String,
pub author: String,
pub author: u64,
}
#[derive(Serialize, Deserialize, Clone)]
pub struct DatabaseSetting {
Expand Down
111 changes: 111 additions & 0 deletions rain-bot/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,118 @@
use common::setting::SettingAll;
use serenity::all::{
ChannelId, Color, Context, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter,
CreateInteractionResponse, CreateInteractionResponseMessage, CreateMessage, User, UserId,
};
use thiserror::Error;

#[derive(Debug, Error)]
pub enum MyError {
#[error("Test")]
Test,
}

enum Severity {
Critical,
FalsePossitive,
CanBeHandledManually,
}

impl MyError {
pub fn severity(&self) -> Severity {
todo!()
}
pub fn advice(&self) -> String {
todo!()
}
pub fn log(&self) {
todo!()
}
}

pub struct ErrorHandling {
pub err: MyError,
pub author: User,
pub effected_user: User,
pub location: String,
pub log_channel: u64,
}

impl ErrorHandling {
pub async fn new(
err: MyError,
ctx: &Context,
setting: &SettingAll,
effected_user: User,
location: String,
) -> Self {
let thor = UserId::new(setting.main.discord.author);
let author = thor.to_user(&ctx.http).await.unwrap_or_default();
Self {
err,
author,
effected_user,
location,
log_channel: setting.discord.channel.error_channel,
}
}

pub fn response(&self) -> CreateInteractionResponse {
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new().embed(self.embed()),
)
}
pub async fn channel_send(&self, ctx: &Context) {
let ch = ChannelId::new(self.log_channel);
if ch
.send_message(
&ctx.http,
CreateMessage::new()
.embed(self.embed())
.content(format!("for {}", self.effected_user)),
)
.await
.is_err()
{
log::error!(
"error sending log to channel, the error is: {:?}, on: {}, and user effected: {}",
self.err,
self.location,
self.effected_user.name
)
}
}

fn embed(&self) -> CreateEmbed {
let color = match self.err.severity() {
Severity::Critical => Color::RED,
Severity::FalsePossitive => Color::DARK_GREEN,
Severity::CanBeHandledManually => Color::ORANGE,
};
CreateEmbed::default()
.color(color)
.title("🛑 Error Occured 🛑")
.description("some cant be handled error occured")
.fields(vec![
(
"🚧 occured on",
format!("**{}**", self.location.to_uppercase()),
false,
),
("📜 error message", format!("> {}", &self.err), false),
(
"⛑ author advice",
format!("```\n{}\n```", &self.err.advice()),
false,
),
])
.author(
CreateEmbedAuthor::new(&self.effected_user.name)
.icon_url(self.effected_user.face()),
)
.footer(
CreateEmbedFooter::new(format!("you can consult this to {}", self.author.tag()))
.icon_url(self.author.face()),
)
.thumbnail("https://media.discordapp.net/attachments/1068877712841789490/1303771799246344272/panics.png?ex=6730435b&is=672ef1db&hm=5f6e31b20eb02607c29ae1a961d97b694dee45ccbdc7889638edc4a6f93903a3&=&format=webp&quality=lossless&width=1000&height=660")
}
}
54 changes: 50 additions & 4 deletions rain-bot/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use serenity::all::*;
use std::{collections::HashMap, sync::Arc};
use tokio::sync::RwLock;

use crate::error::MyError;
use crate::error::{ErrorHandling, MyError};

pub type MyResult<T> = Result<T, MyError>;

Expand All @@ -19,15 +19,61 @@ pub struct DiscordHandler<T: CommandInteractionTrait> {
#[async_trait]
pub trait CommandInteractionTrait: Sync + Send + 'static {
async fn hand(&self, app: Arc<App>, cmd: CommandInteraction, ctx: Context) {
if let Err(e) = Self::handle(app, cmd, ctx).await {
// TODO: Proper error handling
log::error!("there is error {:?}", e);
if let Err(e) = Self::handle(app.clone(), cmd.clone(), ctx.clone()).await {
e.log();
let setting = app.setting.read().await;
let err = ErrorHandling::new(e, &ctx, &setting, cmd.user.clone(), Self::name()).await;
if cmd
.create_response(&ctx.http, err.response())
.await
.is_err()
{
err.channel_send(&ctx).await
}
}
}
async fn handle(app: Arc<App>, cmd: CommandInteraction, ctx: Context) -> MyResult<()>;
fn command() -> CreateCommand;
fn name() -> String;
}
#[async_trait]
pub trait ButtonInteractionTrait: Sync + Send + 'static {
async fn hand(&self, app: Arc<App>, cmd: ComponentInteraction, ctx: Context) {
if let Err(e) = Self::handle(app.clone(), cmd.clone(), ctx.clone()).await {
e.log();
let setting = app.setting.read().await;
let err = ErrorHandling::new(e, &ctx, &setting, cmd.user.clone(), Self::name()).await;
if cmd
.create_response(&ctx.http, err.response())
.await
.is_err()
{
err.channel_send(&ctx).await
}
}
}
async fn handle(app: Arc<App>, cmd: ComponentInteraction, ctx: Context) -> MyResult<()>;
fn name() -> String;
}
#[async_trait]
pub trait ModalInteractionTrait: Sync + Send + 'static {
async fn hand(&self, app: Arc<App>, cmd: ModalInteraction, ctx: Context) {
if let Err(e) = Self::handle(app.clone(), cmd.clone(), ctx.clone()).await {
e.log();
let setting = app.setting.read().await;
let err = ErrorHandling::new(e, &ctx, &setting, cmd.user.clone(), Self::name()).await;
if cmd
.create_response(&ctx.http, err.response())
.await
.is_err()
{
err.channel_send(&ctx).await
}
}
}
async fn handle(app: Arc<App>, cmd: ModalInteraction, ctx: Context) -> MyResult<()>;
fn name() -> String;
}

#[async_trait]
impl<T: CommandInteractionTrait> EventHandler for DiscordHandler<T> {
Expand Down

0 comments on commit 67f6779

Please sign in to comment.