Skip to content

Commit 66a5b5f

Browse files
authored
Allow edit failures to be dispatched to users as an internal error, prevent empty components on embed send (#234)
1 parent 10e8407 commit 66a5b5f

File tree

8 files changed

+74
-65
lines changed

8 files changed

+74
-65
lines changed

src/cache.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use lru_cache::LruCache;
2020
use serenity::all::{ApplicationId, CommandInteraction, ShardManager};
2121
use serenity::model::channel::Message;
2222

23-
/** Caching **/
23+
/* Caching */
2424

2525
/// Contains bot configuration information provided mostly from environment variables
2626
pub struct ConfigCache;

src/commands/asm.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use serenity::{
66
};
77

88
use crate::cache::{CompilerCache, ConfigCache, LinkAPICache, MessageCache, MessageCacheEntry};
9-
use crate::utls::constants::*;
109
use crate::utls::discordhelpers;
1110

1211
use crate::managers::compilation::CompilationDetails;
@@ -41,8 +40,7 @@ pub async fn asm(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
4140
let asm_embed = msg.channel_id.send_message(&ctx.http, new_msg).await?;
4241

4342
// Success/fail react
44-
let compilation_successful = asm_embed.embeds[0].colour.unwrap().0 == COLOR_OKAY;
45-
discordhelpers::send_completion_react(ctx, &asm_embed, compilation_successful).await?;
43+
discordhelpers::send_completion_react(ctx, &asm_embed, compilation_details.success).await?;
4644

4745
let data_read = ctx.data.read().await;
4846
let mut message_cache = data_read.get::<MessageCache>().unwrap().lock().await;

src/commands/compile.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::fmt::Write as _;
33
use serenity::framework::standard::{macros::command, Args, CommandResult};
44

55
use crate::cache::{LinkAPICache, MessageCache, MessageCacheEntry};
6-
use crate::utls::constants::COLOR_OKAY;
76
use crate::utls::discordhelpers::embeds;
87
use crate::utls::{discordhelpers, parser};
98

@@ -46,8 +45,7 @@ pub async fn compile(ctx: &Context, msg: &Message, _args: Args) -> CommandResult
4645
let sent = msg.channel_id.send_message(&ctx.http, new_msg).await?;
4746

4847
// Success/fail react
49-
let compilation_successful = sent.embeds[0].colour.unwrap().0 == COLOR_OKAY;
50-
discordhelpers::send_completion_react(ctx, &sent, compilation_successful).await?;
48+
discordhelpers::send_completion_react(ctx, &sent, compilation_details.success).await?;
5149

5250
let mut delete_cache = data_read.get::<MessageCache>().unwrap().lock().await;
5351
delete_cache.insert(msg.id.get(), MessageCacheEntry::new(sent, msg.clone()));
@@ -123,7 +121,7 @@ pub async fn handle_request(
123121
// remove our loading emote
124122
let _ = discordhelpers::delete_bot_reacts(&ctx, msg, loading_reaction).await;
125123

126-
let is_success = &result.0.success;
124+
let is_success = result.0.success;
127125
{
128126
// stats manager is used in events.rs, lets keep our locks very short
129127
let stats = data_read.get::<StatsManagerCache>().unwrap().lock().await;
@@ -142,7 +140,7 @@ pub async fn handle_request(
142140
"<<unknown>>".to_owned()
143141
};
144142
let emb = embeds::build_complog_embed(
145-
*is_success,
143+
is_success,
146144
&parse_result.code,
147145
&parse_result.target,
148146
&msg.author.name,

src/events.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,17 +187,33 @@ impl EventHandler for Handler {
187187
.map(|msg| msg.clone())
188188
};
189189

190-
if let Some(msg) = maybe_message {
190+
if let Some(mut msg) = maybe_message {
191191
if let Some(new_msg) = new_data.content {
192192
if let Some(author) = new_data.author {
193-
discordhelpers::handle_edit(
193+
if let Err(e) = discordhelpers::handle_edit(
194194
&ctx,
195195
new_msg,
196-
author,
196+
author.clone(),
197197
msg.our_msg.clone(),
198198
msg.original_msg.clone(),
199199
)
200-
.await;
200+
.await
201+
{
202+
let emb = embeds::build_fail_embed(
203+
&author,
204+
&format!("An internal error occurred doing your request:\n{}", e),
205+
);
206+
if let Err(e) = embeds::edit_message_embed(
207+
&ctx,
208+
&mut msg.our_msg,
209+
&mut emb.clone(),
210+
None,
211+
)
212+
.await
213+
{
214+
error!("Could not edit sent message! Original error: {}", e);
215+
}
216+
}
201217
}
202218
}
203219
}

src/managers/compilation.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ impl CompilationManager {
306306

307307
builder.build(wbox)?;
308308
let res = builder.dispatch().await?;
309+
details.success = res.status.eq("0");
309310
Ok((details, res))
310311
}
311312
}

src/tests/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pub mod boilerplate;
22
pub mod cpp;
33
#[cfg(test)]
4-
#[cfg_attr(feature = "cargo-clippy", allow(clippy::all))]
4+
#[cfg_attr(feature = "clippy", allow(clippy::all))]
55
pub mod parser;

src/utls/discordhelpers/embeds.rs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use std::fmt::Write as _;
22
use std::{env, str};
33

4+
use crate::apis::insights::InsightsResponse;
5+
use crate::cache::LinkAPICache;
6+
use crate::managers::compilation::CompilationDetails;
47
use serenity::all::{CreateActionRow, CreateButton, CreateEmbedFooter, EditMessage};
58
use serenity::http::Http;
69
use serenity::{
@@ -9,10 +12,6 @@ use serenity::{
912
model::prelude::*,
1013
};
1114

12-
use crate::apis::insights::InsightsResponse;
13-
use crate::cache::LinkAPICache;
14-
use crate::managers::compilation::CompilationDetails;
15-
1615
use crate::utls::constants::*;
1716
use crate::utls::discordhelpers;
1817

@@ -49,19 +48,16 @@ impl ToEmbed for wandbox::CompilationResult {
4948

5049
if !self.signal.is_empty() {
5150
// If we received 'Signal', then the application successfully ran, but was timed out
52-
// by wandbox. We should skin this as successful, so we set status to 0 (success).
53-
// This is done to ensure that the checkmark is added at the end of the compile
54-
// command hook.
51+
// by wandbox. We should skin this as successful as it causes confusion as to who
52+
// actually failed (ourselves vs wandbox)
5553
embed = embed.color(COLOR_OKAY);
5654
}
5755
if !self.compiler_all.is_empty() {
58-
let str =
59-
discordhelpers::conform_external_str(&self.compiler_all, MAX_ERROR_LEN, true);
56+
let str = discordhelpers::conform_external_str(&self.compiler_all, MAX_ERROR_LEN, true);
6057
embed = embed.field("Compiler Output", format!("```{}\n```", str), false);
6158
}
6259
if !self.program_all.is_empty() {
63-
let str =
64-
discordhelpers::conform_external_str(&self.program_all, MAX_OUTPUT_LEN, true);
60+
let str = discordhelpers::conform_external_str(&self.program_all, MAX_OUTPUT_LEN, true);
6561
embed = embed.field("Program Output", format!("```\n{}\n```", str), false);
6662
}
6763
if !self.url.is_empty() {
@@ -186,14 +182,8 @@ impl ToEmbed for godbolt::GodboltResponse {
186182
}
187183

188184
if !output {
189-
embed = embed
190-
.title("Compilation successful")
191-
.description("No output.");
185+
embed = embed.title("Compilation successful");
192186
}
193-
194-
// Execution time can be displayed here, but I don't think it's useful enough
195-
// to show...
196-
//embed.field("Execution Time", format!("`{}ms`", self.execution_time), true);
197187
}
198188

199189
let mut appendstr = author.name.clone();
@@ -215,17 +205,17 @@ impl ToEmbed for godbolt::GodboltResponse {
215205
pub async fn edit_message_embed(
216206
ctx: &Context,
217207
old: &mut Message,
218-
emb: CreateEmbed,
208+
emb: &mut CreateEmbed,
219209
compilation_details: Option<CompilationDetails>,
220-
) {
210+
) -> serenity::Result<()> {
221211
let mut url = None;
222212
if let Some(details) = compilation_details {
223213
let data = ctx.data.read().await;
224214
if let Some(link_cache) = data.get::<LinkAPICache>() {
225215
if let Some(b64) = details.base64 {
226216
let long_url = format!("https://godbolt.org/clientstate/{}", b64);
227217
let link_cache_lock = link_cache.read().await;
228-
url = link_cache_lock.get_link(long_url).await
218+
url = link_cache_lock.get_link(long_url).await;
229219
}
230220
}
231221
}
@@ -236,10 +226,18 @@ pub async fn edit_message_embed(
236226
btns.push(CreateButton::new_link(shorturl).label("View on godbolt.org"));
237227
}
238228

239-
let edit = EditMessage::new()
240-
.embed(emb)
241-
.components(vec![CreateActionRow::Buttons(btns)]);
242-
let _ = old.edit(ctx, edit).await;
229+
let edit = {
230+
if btns.is_empty() {
231+
EditMessage::default().embed(emb.clone())
232+
} else {
233+
EditMessage::default()
234+
.components(vec![CreateActionRow::Buttons(btns)])
235+
.embed(emb.clone())
236+
}
237+
};
238+
239+
old.edit(ctx, edit).await?;
240+
Ok(())
243241
}
244242

245243
pub fn build_insights_response_embed(author: &User, res: InsightsResponse) -> CreateEmbed {

src/utls/discordhelpers/mod.rs

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub async fn handle_edit(
9191
author: User,
9292
mut old: Message,
9393
original_message: Message,
94-
) {
94+
) -> serenity::Result<()> {
9595
let prefix = {
9696
let data = ctx.data.read().await;
9797
let info = data.get::<ConfigCache>().unwrap().read().await;
@@ -122,8 +122,8 @@ pub async fn handle_edit(
122122
)
123123
.await
124124
{
125-
let err = embeds::build_fail_embed(&author, &e.to_string());
126-
embeds::edit_message_embed(ctx, &mut old, err, None).await;
125+
let mut err = embeds::build_fail_embed(&author, &e.to_string());
126+
embeds::edit_message_embed(ctx, &mut old, &mut err, None).await?;
127127
}
128128
} else if content.starts_with(&format!("{}compile", prefix)) {
129129
if let Err(e) = handle_edit_compile(
@@ -135,8 +135,8 @@ pub async fn handle_edit(
135135
)
136136
.await
137137
{
138-
let err = embeds::build_fail_embed(&author, &e.to_string());
139-
embeds::edit_message_embed(ctx, &mut old, err, None).await;
138+
let mut err = embeds::build_fail_embed(&author, &e.to_string());
139+
embeds::edit_message_embed(ctx, &mut old, &mut err, None).await?;
140140
}
141141
} else if content.starts_with(&format!("{}cpp", prefix)) {
142142
if let Err(e) = handle_edit_cpp(
@@ -148,8 +148,8 @@ pub async fn handle_edit(
148148
)
149149
.await
150150
{
151-
let err = embeds::build_fail_embed(&author, &e.to_string());
152-
embeds::edit_message_embed(ctx, &mut old, err, None).await;
151+
let mut err = embeds::build_fail_embed(&author, &e.to_string());
152+
embeds::edit_message_embed(ctx, &mut old, &mut err, None).await?;
153153
}
154154
} else if content.starts_with(&format!("{}insights", prefix)) {
155155
if let Err(e) = handle_edit_insights(
@@ -161,13 +161,15 @@ pub async fn handle_edit(
161161
)
162162
.await
163163
{
164-
let err = embeds::build_fail_embed(&author, &e.to_string());
165-
embeds::edit_message_embed(ctx, &mut old, err, None).await;
164+
let mut err = embeds::build_fail_embed(&author, &e.to_string());
165+
embeds::edit_message_embed(ctx, &mut old, &mut err, None).await?;
166166
}
167167
} else {
168-
let err = embeds::build_fail_embed(&author, "Invalid command for edit functionality!");
169-
embeds::edit_message_embed(ctx, &mut old, err, None).await;
168+
let mut err = embeds::build_fail_embed(&author, "Invalid command for edit functionality!");
169+
embeds::edit_message_embed(ctx, &mut old, &mut err, None).await?;
170170
}
171+
172+
Ok(())
171173
}
172174

173175
pub async fn handle_edit_insights(
@@ -177,14 +179,13 @@ pub async fn handle_edit_insights(
177179
mut old: Message,
178180
original_msg: Message,
179181
) -> CommandResult {
180-
let (details, embed) =
182+
let (details, mut embed) =
181183
crate::commands::insights::handle_request(ctx.clone(), content, author, &original_msg)
182184
.await?;
183185

184-
let compilation_successful = details.success;
185-
discordhelpers::send_completion_react(ctx, &old, compilation_successful).await?;
186+
discordhelpers::send_completion_react(ctx, &old, details.success).await?;
186187

187-
embeds::edit_message_embed(ctx, &mut old, embed, None).await;
188+
embeds::edit_message_embed(ctx, &mut old, &mut embed, None).await?;
188189
Ok(())
189190
}
190191

@@ -195,13 +196,12 @@ pub async fn handle_edit_cpp(
195196
mut old: Message,
196197
original_msg: Message,
197198
) -> CommandResult {
198-
let (embed, details) =
199+
let (mut embed, details) =
199200
crate::commands::cpp::handle_request(ctx.clone(), content, author, &original_msg).await?;
200201

201-
let compilation_successful = details.success;
202-
discordhelpers::send_completion_react(ctx, &old, compilation_successful).await?;
202+
discordhelpers::send_completion_react(ctx, &old, details.success).await?;
203203

204-
embeds::edit_message_embed(ctx, &mut old, embed, Some(details)).await;
204+
embeds::edit_message_embed(ctx, &mut old, &mut embed, Some(details)).await?;
205205
Ok(())
206206
}
207207

@@ -212,13 +212,13 @@ pub async fn handle_edit_compile(
212212
mut old: Message,
213213
original_msg: Message,
214214
) -> CommandResult {
215-
let (embed, compilation_details) =
215+
let (mut embed, compilation_details) =
216216
compile::handle_request(ctx.clone(), content, author, &original_msg).await?;
217217

218218
let compilation_successful = compilation_details.success;
219219
discordhelpers::send_completion_react(ctx, &old, compilation_successful).await?;
220220

221-
embeds::edit_message_embed(ctx, &mut old, embed, Some(compilation_details)).await;
221+
embeds::edit_message_embed(ctx, &mut old, &mut embed, Some(compilation_details)).await?;
222222
Ok(())
223223
}
224224

@@ -229,13 +229,11 @@ pub async fn handle_edit_asm(
229229
mut old: Message,
230230
original_msg: Message,
231231
) -> CommandResult {
232-
let (emb, details) =
232+
let (mut emb, details) =
233233
crate::commands::asm::handle_request(ctx.clone(), content, author, &original_msg).await?;
234234

235-
let success = details.success;
236-
embeds::edit_message_embed(ctx, &mut old, emb, Some(details)).await;
237-
238-
send_completion_react(ctx, &old, success).await?;
235+
send_completion_react(ctx, &old, details.success).await?;
236+
embeds::edit_message_embed(ctx, &mut old, &mut emb, Some(details)).await?;
239237
Ok(())
240238
}
241239

0 commit comments

Comments
 (0)