tulpje_framework/handler/
command_handler.rs1use std::{future::Future, pin::Pin};
2
3use twilight_model::channel::message::MessageFlags;
4use twilight_util::builder::message::{ContainerBuilder, TextDisplayBuilder};
5
6use super::super::context::CommandContext;
7
8use crate::{Error, color};
9
10pub(crate) type CommandFunc<T> =
11 fn(CommandContext<T>) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send>>;
12
13#[derive(Clone)]
14pub struct CommandHandler<T: Clone + Send + Sync> {
15 pub module: String,
16 pub name: String,
17 pub func: CommandFunc<T>,
18}
19
20impl<T: Clone + Send + Sync> CommandHandler<T> {
21 #[tracing::instrument(name="command-handler", skip_all, fields(
22 module=self.module,
23 name=self.name
24 ))]
25 pub async fn run(&self, ctx: CommandContext<T>) -> Result<(), Error> {
26 if let Err(err) = (self.func)(ctx.clone()).await {
29 tracing::error!(
30 "error during command {}, sending reference to client: {}",
31 self.name,
32 err
33 );
34
35 if let Some(chan) = &ctx.event.channel {
36 ctx.client
37 .create_message(chan.id)
38 .flags(MessageFlags::IS_COMPONENTS_V2)
39 .components(&[ContainerBuilder::new()
40 .accent_color(Some(*color::roles::RED))
41 .component(
42 TextDisplayBuilder::new(format!(
44 "### Internal Error\n{}\n**Error Code**\n```{}```",
45 std::env::var("TULPJE_EXTRA_ERROR_MESSAGE").unwrap_or_default(),
46 ctx.meta.uuid
47 ))
48 .build(),
49 )
50 .build()
51 .into()])
52 .await?;
53 } else {
54 tracing::warn!(event = ?ctx.event, "channel on event was empty, can't send error");
55 }
56 }
57
58 Ok(())
59 }
60}