2 Commits

Author SHA1 Message Date
cc5f6d9d55 Bump version 2025-06-18 22:13:05 +01:00
761d545496 Improve errors and wording 2025-06-18 22:08:32 +01:00
8 changed files with 121 additions and 26 deletions

4
Cargo.lock generated
View File

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "addr2line"
@ -2614,7 +2614,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "reminder-rs"
version = "1.7.37"
version = "1.7.38"
dependencies = [
"base64 0.22.1",
"chrono",

View File

@ -1,6 +1,6 @@
[package]
name = "reminder-rs"
version = "1.7.37"
version = "1.7.38"
authors = ["Jude Southworth <judesouthworth@pm.me>"]
edition = "2021"
license = "AGPL-3.0 only"

View File

@ -75,8 +75,8 @@ Please select a unique name for your macro.",
CreateEmbed::new()
.title("Macro Recording Started")
.description(
"Run up to 5 commands, or type `/macro finish` to stop at any point.
Any commands ran as part of recording will be inconsequential",
"Run up to 5 commands to record in this macro. Use `/macro finish` to stop recording at any point.
Any commands performed during recording won't take any actual action- they are only captured for the macro.",
)
.color(*THEME_COLOR),
),

View File

@ -1,4 +1,6 @@
use poise::{CommandInteractionType, CreateReply};
use crate::consts::THEME_COLOR;
use poise::{serenity_prelude::CreateEmbed, CommandInteractionType, CreateReply};
use serenity::builder::CreateEmbedFooter;
use crate::{consts::MACRO_MAX_COMMANDS, models::command_macro::RecordedCommand, Context, Error};
@ -18,7 +20,18 @@ async fn macro_check(ctx: Context<'_>) -> bool {
.send(
CreateReply::default()
.ephemeral(true)
.content(format!("{} commands already recorded. Please use `/macro finish` to end recording.", MACRO_MAX_COMMANDS))
.embed(CreateEmbed::new()
.title("💾 Currently recording macro")
.description(
format!("{} commands already recorded. Please use `/macro finish` to end recording.", MACRO_MAX_COMMANDS),
)
.footer(
CreateEmbedFooter::new(
"Any commands performed during recording won't take any actual action- they are only captured for the macro"
)
)
.color(*THEME_COLOR),
),
)
.await;
} else {
@ -28,9 +41,19 @@ async fn macro_check(ctx: Context<'_>) -> bool {
let _ = ctx
.send(
CreateReply::default()
.ephemeral(true)
.content("Command recorded to macro"),
CreateReply::default().ephemeral(true).embed(
CreateEmbed::new()
.title("💾 Currently recording macro")
.description(
"Command recorded. Use `/macro finish` to end recording.",
)
.footer(
CreateEmbedFooter::new(
"Any commands performed during recording won't take any actual action- they are only captured for the macro"
)
)
.color(*THEME_COLOR),
),
)
.await;
}
@ -38,8 +61,18 @@ async fn macro_check(ctx: Context<'_>) -> bool {
None => {
let _ = ctx
.send(
CreateReply::default().ephemeral(true).content(
"This command is not supported in macros yet.",
CreateReply::default().ephemeral(true).embed(
CreateEmbed::new()
.title("💾 Currently recording macro")
.description(
"This command is not supported in macros, so it hasn't been recorded. Use `/macro finish` to end recording.",
)
.footer(
CreateEmbedFooter::new(
"Any commands performed during recording won't take any actual action- they are only captured for the macro"
)
)
.color(*THEME_COLOR),
),
)
.await;
@ -74,6 +107,7 @@ async fn check_self_permissions(ctx: Context<'_>) -> bool {
return if permissions.send_messages()
&& permissions.embed_links()
&& manage_webhooks
&& permissions.view_channel()
{
true
} else {
@ -81,12 +115,13 @@ async fn check_self_permissions(ctx: Context<'_>) -> bool {
.send(CreateReply::default().content(format!(
"The bot appears to be missing some permissions:
{} **View Channels**
{} **Send Message**
{} **Embed Links**
{} **Manage Webhooks**
Please check the bot's roles, and any channel overrides. Alternatively, giving the bot
\"Administrator\" will bypass permission checks",
Please check the bot's roles, and any channel overrides. Alternatively, giving the bot \"Administrator\" will bypass permission checks",
if permissions.view_channel() { "" } else { "" },
if permissions.send_messages() { "" } else { "" },
if permissions.embed_links() { "" } else { "" },
if manage_webhooks { "" } else { "" },
@ -100,9 +135,7 @@ Please check the bot's roles, and any channel overrides. Alternatively, giving t
manage_webhooks
}
None => {
return true;
}
None => true,
}
}

View File

@ -92,6 +92,8 @@ enum Error {
SQLx(sqlx::Error),
#[allow(unused)]
Serenity(serenity::Error),
#[allow(unused)]
MissingDiscordPermission(&'static str),
}
pub async fn initialize(

View File

@ -305,7 +305,15 @@ pub async fn edit_reminder(
Err(e) => {
warn!("`create_database_channel` returned an error code: {:?}", e);
error.push("Failed to configure channel for reminders. Please check the bot permissions".to_string());
// Provide more specific error messages based on the error type
match e {
crate::web::Error::MissingDiscordPermission(permission) => {
error.push(format!("Please ensure the bot has the \"{}\" permission in the channel", permission));
}
_ => {
error.push("Failed to configure channel for reminders. Please check the bot permissions".to_string());
}
}
}
}
}

View File

@ -65,7 +65,16 @@ pub async fn create_reminder(
if let Err(e) = channel {
warn!("`create_database_channel` returned an error code: {:?}", e);
return Err(json!({"error": "Failed to configure channel for reminders."}));
// Provide more specific error messages based on the error type
let error_msg = match e {
Error::MissingDiscordPermission(permission) => format!(
"Please ensure the bot has the \"{}\" permission in the channel",
permission
),
_ => "Failed to configure channel for reminders.".to_string(),
};
return Err(json!({"error": error_msg}));
}
let channel = channel.unwrap();

View File

@ -10,6 +10,7 @@ use rocket::{
use rocket_dyn_templates::Template;
use secrecy::ExposeSecret;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use serenity::http::HttpError;
use serenity::{
all::CacheHttp,
builder::CreateWebhook,
@ -404,9 +405,19 @@ pub(crate) async fn create_reminder(
if let Err(e) = channel {
warn!("`create_database_channel` returned an error code: {:?}", e);
return Err(
json!({"error": "Failed to configure channel for reminders. Please check the bot permissions"}),
);
// Provide more specific error messages based on the error type
let error_msg = match e {
Error::MissingDiscordPermission(permission) => {
format!(
"Please ensure the bot has the \"{}\" permission in the channel",
permission
)
}
_ => "Failed to configure channel for reminders. Please check the bot permissions"
.to_string(),
};
return Err(json!({"error": error_msg}));
}
let channel = channel.unwrap();
@ -716,13 +727,36 @@ async fn create_database_channel(
match row {
Ok(row) => {
let is_dm =
channel.to_channel(&ctx).await.map_err(|e| Error::Serenity(e))?.private().is_some();
let is_dm = channel
.to_channel(&ctx)
.await
.map_err(|e| {
if let serenity::Error::Http(http_error) = &e {
if let HttpError::UnsuccessfulRequest(response) = http_error {
if response.error.code == 50001 {
return Error::MissingDiscordPermission("View Channel");
}
}
}
Error::Serenity(e)
})?
.private()
.is_some();
if !is_dm && (row.webhook_token.is_none() || row.webhook_id.is_none()) {
let webhook = channel
.create_webhook(&ctx, CreateWebhook::new("Reminder").avatar(&*DEFAULT_AVATAR))
.await
.map_err(|e| Error::Serenity(e))?;
.map_err(|e| match &e {
serenity::Error::Http(HttpError::UnsuccessfulRequest(response)) => {
match response.error.code {
50001 => Error::MissingDiscordPermission("View Channel"),
50013 => Error::MissingDiscordPermission("Manage Webhooks"),
_ => Error::Serenity(e),
}
}
_ => Error::Serenity(e),
})?;
let token = webhook.token.unwrap();
@ -747,7 +781,16 @@ async fn create_database_channel(
let webhook = channel
.create_webhook(&ctx, CreateWebhook::new("Reminder").avatar(&*DEFAULT_AVATAR))
.await
.map_err(|e| Error::Serenity(e))?;
.map_err(|e| match &e {
serenity::Error::Http(HttpError::UnsuccessfulRequest(response)) => {
match response.error.code {
50001 => Error::MissingDiscordPermission("View Channel"),
50013 => Error::MissingDiscordPermission("Manage Webhooks"),
_ => Error::Serenity(e),
}
}
_ => Error::Serenity(e),
})?;
let token = webhook.token.unwrap();