Skip to content

Commit 7cfd41d

Browse files
committed
feat(error_handling): log event errors to Discord
1 parent 8a5cb04 commit 7cfd41d

File tree

3 files changed

+59
-34
lines changed

3 files changed

+59
-34
lines changed

src/commands/fun/shiggy.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use poise::{serenity_prelude as serenity, CreateReply};
22

33
use crate::{utils::error_handling::ValfiskError, Context};
4-
use color_eyre::eyre::Result;
4+
use color_eyre::eyre::{Report, Result};
55

66
#[derive(serde::Deserialize)]
77
struct SafebooruResponse {
@@ -55,8 +55,9 @@ pub async fn shiggy(
5555
}
5656

5757
Err(err) => {
58-
let err = color_eyre::eyre::Report::from(err);
59-
let valfisk_err = ValfiskError::new(&err, &ctx);
58+
let err = Report::from(err);
59+
60+
let valfisk_err = ValfiskError::error(&err, &ctx);
6061
valfisk_err.handle_log();
6162
valfisk_err.handle_report().await;
6263

src/handlers/error_handling.rs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,51 @@
11
use tracing::error;
22

3-
use poise::FrameworkError;
3+
use poise::{
4+
serenity_prelude::{CacheHttp, CreateEmbed, CreateMessage, Timestamp},
5+
FrameworkError,
6+
};
47

5-
use crate::{utils::error_handling::ValfiskError, Data};
8+
use crate::{
9+
utils::error_handling::{ValfiskError, ERROR_LOGS_CHANNEL},
10+
Data,
11+
};
612

713
#[tracing::instrument(skip(err))]
814
pub async fn handle_error(err: FrameworkError<'_, Data, color_eyre::eyre::Report>) {
915
match err {
10-
FrameworkError::EventHandler { error, .. } => {
16+
FrameworkError::EventHandler {
17+
error,
18+
event,
19+
framework,
20+
..
21+
} => {
1122
error!("{:?}", error);
23+
24+
let embed = CreateEmbed::default()
25+
.title("An error occurred in an event handler!")
26+
.description(format!(
27+
"### Error\n```\n{error:#?}\n```\n### Event\n```\n{event:#?}\n```"
28+
))
29+
.timestamp(Timestamp::now())
30+
.color(0xff6b6b);
31+
32+
if let Some(channel) = *ERROR_LOGS_CHANNEL {
33+
channel
34+
.send_message(
35+
framework.serenity_context.http(),
36+
CreateMessage::default().embed(embed),
37+
)
38+
.await
39+
.ok();
40+
}
1241
}
1342

1443
FrameworkError::Command { error, ctx, .. } => {
15-
ValfiskError::new(&error, &ctx).handle_all().await;
44+
ValfiskError::error(&error, &ctx).handle_all().await;
1645
}
1746

1847
FrameworkError::CommandPanic { payload, ctx, .. } => {
19-
ValfiskError::new(&payload, &ctx).handle_all().await;
48+
ValfiskError::panic(&payload, &ctx).handle_all().await;
2049
}
2150

2251
_ => {}

src/utils/error_handling.rs

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use once_cell::sync::Lazy;
12
use std::fmt::Debug;
23

34
use nanoid::nanoid;
@@ -17,18 +18,6 @@ pub enum ErrorOrPanic<'a> {
1718
Panic(&'a Option<String>),
1819
}
1920

20-
impl<'a> From<&'a color_eyre::eyre::Error> for ErrorOrPanic<'a> {
21-
fn from(val: &'a color_eyre::eyre::Error) -> Self {
22-
ErrorOrPanic::Error(val)
23-
}
24-
}
25-
26-
impl<'a> From<&'a Option<String>> for ErrorOrPanic<'a> {
27-
fn from(val: &'a Option<String>) -> Self {
28-
ErrorOrPanic::Panic(val)
29-
}
30-
}
31-
3221
impl ErrorOrPanic<'_> {
3322
/// Return whether `self` is a panic or an error.
3423
fn type_string(&self) -> String {
@@ -39,6 +28,12 @@ impl ErrorOrPanic<'_> {
3928
}
4029
}
4130

31+
pub static ERROR_LOGS_CHANNEL: Lazy<Option<ChannelId>> = Lazy::new(|| {
32+
std::env::var("ERROR_LOGS_CHANNEL")
33+
.ok()
34+
.and_then(|s| s.parse::<ChannelId>().ok())
35+
});
36+
4237
/// A wrapped type around errors or panics encapsulated in [`ErrorOrPanic`] that includes context from Poise and a randomly generated `error_id`.
4338
#[derive(Debug)]
4439
pub struct ValfiskError<'a> {
@@ -51,14 +46,21 @@ pub struct ValfiskError<'a> {
5146
}
5247

5348
impl ValfiskError<'_> {
54-
/// Create a new [`ValfiskError`] from an error or a panic string and Poise context.
49+
/// Create a new [`ValfiskError`] from an error and Poise context.
5550
#[must_use]
56-
pub fn new<'a>(
57-
error_or_panic: impl Into<ErrorOrPanic<'a>>,
58-
ctx: &'a Context,
59-
) -> ValfiskError<'a> {
51+
pub fn error<'a>(error: &'a color_eyre::eyre::Error, ctx: &'a Context) -> ValfiskError<'a> {
6052
ValfiskError {
61-
error_or_panic: error_or_panic.into(),
53+
error_or_panic: ErrorOrPanic::Error(error),
54+
ctx,
55+
error_id: nanoid!(8),
56+
}
57+
}
58+
59+
/// Create a new [`ValfiskError`] from a panic string and Poise context.
60+
#[must_use]
61+
pub fn panic<'a>(panic: &'a Option<String>, ctx: &'a Context) -> ValfiskError<'a> {
62+
ValfiskError {
63+
error_or_panic: ErrorOrPanic::Panic(panic),
6264
ctx,
6365
error_id: nanoid!(8),
6466
}
@@ -91,14 +93,7 @@ impl ValfiskError<'_> {
9193
/// Report the error to a channel defined through the environment variable `ERROR_LOGS_CHANNEL`.
9294
#[tracing::instrument(skip(self))]
9395
pub async fn handle_report(&self) {
94-
if let Ok(channel_id) = match std::env::var("ERROR_LOGS_CHANNEL") {
95-
Ok(channel_id_str) => channel_id_str
96-
.parse::<u64>()
97-
.map_err(color_eyre::eyre::Error::from),
98-
Err(err) => Err(color_eyre::eyre::Error::from(err)),
99-
} {
100-
let channel = ChannelId::new(channel_id);
101-
96+
if let Some(channel) = *ERROR_LOGS_CHANNEL {
10297
let embed = CreateEmbed::default()
10398
.title("An error occurred!")
10499
.description(format!("```\n{:#?}\n```", self.error_or_panic))

0 commit comments

Comments
 (0)