From 8cdf969a530e487304fb9331e4d19e403968beb1 Mon Sep 17 00:00:00 2001 From: Xevion Date: Fri, 29 Aug 2025 12:09:37 -0500 Subject: [PATCH] feat: command logging, explicit builtin command error handler --- src/bot/commands/gcal.rs | 13 +++--------- src/main.rs | 46 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/bot/commands/gcal.rs b/src/bot/commands/gcal.rs index aa9bb26..613d38b 100644 --- a/src/bot/commands/gcal.rs +++ b/src/bot/commands/gcal.rs @@ -4,7 +4,7 @@ use crate::banner::{Course, DayOfWeek, MeetingScheduleInfo}; use crate::bot::{Context, Error, utils}; use chrono::NaiveDate; use std::collections::HashMap; -use tracing::{error, info}; +use tracing::info; use url::Url; /// Generate a link to create a Google Calendar event for a course @@ -22,19 +22,12 @@ pub async fn gcal( let term = course.term.clone(); // Get meeting times - let meeting_times = match ctx + let meeting_times = ctx .data() .app_state .banner_api .get_course_meeting_time(&term, &crn.to_string()) - .await - { - Ok(meeting_time) => meeting_time, - Err(e) => { - error!("failed to get meeting times: {}", e); - return Err(e); - } - }; + .await?; struct LinkDetail { link: String, diff --git a/src/main.rs b/src/main.rs index 3cb78fd..8b7ca7e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use serenity::all::{ClientBuilder, GatewayIntents}; +use serenity::all::{CacheHttp, ClientBuilder, GatewayIntents}; use tokio::signal; use tracing::{error, info, warn}; use tracing_subscriber::{EnvFilter, FmtSubscriber}; @@ -92,6 +92,50 @@ async fn main() { let framework = poise::Framework::builder() .options(poise::FrameworkOptions { commands: get_commands(), + pre_command: |ctx| { + Box::pin(async move { + let content = match ctx { + poise::Context::Application(_) => ctx.invocation_string(), + poise::Context::Prefix(prefix) => prefix.msg.content.to_string(), + }; + let channel_name = ctx + .channel_id() + .name(ctx.http()) + .await + .unwrap_or("unknown".to_string()); + + let span = tracing::Span::current(); + span.record("command_name", ctx.command().qualified_name.as_str()); + span.record("invocation", ctx.invocation_string()); + span.record("msg.content", content.as_str()); + span.record("msg.author", ctx.author().tag().as_str()); + span.record("msg.id", ctx.id()); + span.record("msg.channel_id", ctx.channel_id().get()); + span.record("msg.channel", &channel_name.as_str()); + + tracing::info!( + command_name = ctx.command().qualified_name.as_str(), + invocation = ctx.invocation_string(), + msg.content = %content, + msg.author = %ctx.author().tag(), + msg.author_id = %ctx.author().id, + msg.id = %ctx.id(), + msg.channel = %channel_name.as_str(), + msg.channel_id = %ctx.channel_id(), + "{} invoked by {}", + ctx.command().name, + ctx.author().tag() + ); + }) + }, + on_error: |error| { + Box::pin(async move { + if let Err(e) = poise::builtins::on_error(error).await { + tracing::error!("Fatal error while sending error message: {}", e); + } + // error!(error = ?error, "command error"); + }) + }, ..Default::default() }) .setup(move |ctx, _ready, framework| {