Skip to content

Commit d13d61f

Browse files
committed
Improve and simplify commands errors
1 parent 24d215a commit d13d61f

File tree

10 files changed

+71
-96
lines changed

10 files changed

+71
-96
lines changed

src/github/webhook.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,10 @@ async fn process_payload(
274274
}
275275
}
276276
if !message.is_empty() {
277+
log::info!("user error: {}", message);
277278
if let Some(issue) = event.issue() {
278279
let cmnt = ErrorComment::new(issue, message);
279280
cmnt.post(&ctx.github).await?;
280-
} else {
281-
log::error!("handling event failed: {:?}", message);
282281
}
283282
}
284283
if other_error {

src/handlers.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,26 @@ impl fmt::Display for HandlerError {
2727
}
2828
}
2929

30+
#[derive(Debug)]
31+
pub struct UserError(String);
32+
33+
impl std::error::Error for UserError {}
34+
35+
impl fmt::Display for UserError {
36+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37+
f.write_str(&self.0)
38+
}
39+
}
40+
41+
macro_rules! inform {
42+
(msg:literal $(,)?) => {
43+
anyhow::bail!(crate::handlers::UserError($msg.into()))
44+
};
45+
($err:expr $(,)?) => {
46+
anyhow::bail!(crate::handlers::UserError($err.into()))
47+
};
48+
}
49+
3050
mod assign;
3151
mod autolabel;
3252
mod backport;
@@ -368,11 +388,15 @@ macro_rules! command_handlers {
368388
if let Some(config) = &config.$name {
369389
$name::handle_command(ctx, config, event, command)
370390
.await
371-
.unwrap_or_else(|err| {
372-
errors.push(HandlerError::Other(err.context(format!(
373-
"error when processing {} command handler",
374-
stringify!($name)
375-
))))
391+
.unwrap_or_else(|mut err| {
392+
if let Some(err) = err.downcast_mut::<UserError>() {
393+
errors.push(HandlerError::Message(std::mem::take(&mut err.0)));
394+
} else {
395+
errors.push(HandlerError::Other(err.context(format!(
396+
"error when processing {} command handler",
397+
stringify!($name)
398+
))));
399+
}
376400
});
377401
} else {
378402
errors.push(HandlerError::Message(format!(

src/handlers/assign.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -525,10 +525,7 @@ pub(super) async fn handle_command(
525525
let issue = event.issue().unwrap();
526526
if issue.is_pr() {
527527
if !issue.is_open() {
528-
issue
529-
.post_comment(&ctx.github, "Assignment is not allowed on a closed PR.")
530-
.await?;
531-
return Ok(());
528+
inform!("Assignment is not allowed on a closed PR.");
532529
}
533530
if matches!(
534531
event,
@@ -612,7 +609,7 @@ pub(super) async fn handle_command(
612609
AssignCommand::Claim => event.user().login.clone(),
613610
AssignCommand::AssignUser { username } => {
614611
if !is_team_member && username != event.user().login {
615-
bail!("Only Rust team members can assign other users");
612+
inform!("Only Rust team members can assign other users");
616613
}
617614
username.clone()
618615
}
@@ -627,7 +624,7 @@ pub(super) async fn handle_command(
627624
e.apply(&ctx.github, String::new()).await?;
628625
return Ok(());
629626
} else {
630-
bail!("Cannot release another user's assignment");
627+
inform!("Cannot release another user's assignment");
631628
}
632629
} else {
633630
let current = &event.user().login;
@@ -639,11 +636,11 @@ pub(super) async fn handle_command(
639636
e.apply(&ctx.github, String::new()).await?;
640637
return Ok(());
641638
} else {
642-
bail!("Cannot release unassigned issue");
639+
inform!("Cannot release unassigned issue");
643640
}
644641
};
645642
}
646-
AssignCommand::RequestReview { .. } => bail!("r? is only allowed on PRs."),
643+
AssignCommand::RequestReview { .. } => inform!("r? is only allowed on PRs."),
647644
};
648645
// Don't re-assign if aleady assigned, e.g. on comment edit
649646
if issue.contain_assignee(&to_assign) {

src/handlers/close.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Allows to close an issue or a PR
22
3-
use crate::{config::CloseConfig, github::Event, handlers::Context, interactions::ErrorComment};
3+
use crate::{config::CloseConfig, github::Event, handlers::Context};
44
use parser::command::close::CloseCommand;
55

66
pub(super) async fn handle_command(
@@ -16,9 +16,7 @@ pub(super) async fn handle_command(
1616
.await
1717
.unwrap_or(false);
1818
if !is_team_member {
19-
let cmnt = ErrorComment::new(&issue, "Only team members can close issues.");
20-
cmnt.post(&ctx.github).await?;
21-
return Ok(());
19+
inform!("Only team members can close issues.");
2220
}
2321
issue.close(&ctx.github).await?;
2422
Ok(())

src/handlers/concern.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
config::ConcernConfig,
77
github::{Event, Label},
88
handlers::Context,
9-
interactions::{EditIssueBody, ErrorComment},
9+
interactions::EditIssueBody,
1010
};
1111
use parser::command::concern::ConcernCommand;
1212

@@ -37,7 +37,7 @@ pub(super) async fn handle_command(
3737
cmd: ConcernCommand,
3838
) -> anyhow::Result<()> {
3939
let Event::IssueComment(issue_comment) = event else {
40-
bail!("concern issued on something other than a issue")
40+
inform!("Concerns can only be issued on an issue");
4141
};
4242
let Some(comment_url) = event.html_url() else {
4343
bail!("unable to retrieve the comment url")
@@ -81,10 +81,9 @@ pub(super) async fn handle_command(
8181
issue.number,
8282
issue_comment.comment.user,
8383
);
84-
ErrorComment::new(&issue, "Only team members in the [team repo](https://github.com/rust-lang/team) can add or resolve concerns.")
85-
.post(&ctx.github)
86-
.await?;
87-
return Ok(());
84+
inform!(
85+
"Only team members in the [team repo](https://github.com/rust-lang/team) can add or resolve concerns."
86+
);
8887
}
8988

9089
let mut client = ctx.db.get().await;

src/handlers/major_change.rs

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use crate::{
66
config::MajorChangeConfig,
77
github::{Event, Issue, IssuesAction, IssuesEvent, Label, ZulipGitHubReference},
88
handlers::Context,
9-
interactions::ErrorComment,
109
};
1110
use anyhow::Context as _;
1211
use async_trait::async_trait;
@@ -113,15 +112,10 @@ pub(super) async fn handle_input(
113112
.iter()
114113
.any(|l| l.name == config.enabling_label)
115114
{
116-
let cmnt = ErrorComment::new(
117-
&event.issue,
118-
format!(
119-
"This issue is not ready for proposals; it lacks the `{}` label.",
120-
config.enabling_label
121-
),
122-
);
123-
cmnt.post(&ctx.github).await?;
124-
return Ok(());
115+
inform!(format!(
116+
"This issue is not ready for proposals; it lacks the `{}` label.",
117+
config.enabling_label
118+
));
125119
}
126120
let (zulip_msg, label_to_add) = match cmd {
127121
Invocation::NewProposal => (
@@ -253,15 +247,10 @@ pub(super) async fn handle_command(
253247
.iter()
254248
.any(|l| l.name == config.enabling_label)
255249
{
256-
let cmnt = ErrorComment::new(
257-
&issue,
258-
&format!(
259-
"This issue cannot be seconded; it lacks the `{}` label.",
260-
config.enabling_label
261-
),
262-
);
263-
cmnt.post(&ctx.github).await?;
264-
return Ok(());
250+
inform!(format!(
251+
"This issue cannot be seconded; it lacks the `{}` label.",
252+
config.enabling_label
253+
));
265254
}
266255

267256
let is_team_member = event
@@ -272,9 +261,7 @@ pub(super) async fn handle_command(
272261
.unwrap_or(false);
273262

274263
if !is_team_member {
275-
let cmnt = ErrorComment::new(&issue, "Only team members can second issues.");
276-
cmnt.post(&ctx.github).await?;
277-
return Ok(());
264+
inform!("Only team members can second issues.");
278265
}
279266

280267
let has_concerns = if let Some(concerns_label) = &config.concerns_label {

src/handlers/nominate.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,9 @@ pub(super) async fn handle_command(
2121
};
2222

2323
if !is_team_member {
24-
let cmnt = ErrorComment::new(
25-
&event.issue().unwrap(),
26-
format!(
27-
"Nominating and approving issues and pull requests is restricted to members of\
28-
the Rust teams."
29-
),
24+
inform!(
25+
"Nominating and approving issues and pull requests is restricted to members of the Rust teams."
3026
);
31-
cmnt.post(&ctx.github).await?;
32-
return Ok(());
3327
}
3428

3529
let issue_labels = event.issue().unwrap().labels();

src/handlers/ping.rs

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use crate::{
88
config::PingConfig,
99
github::{self, Event},
1010
handlers::Context,
11-
interactions::ErrorComment,
1211
};
1312
use parser::command::ping::PingCommand;
1413

@@ -25,42 +24,27 @@ pub(super) async fn handle_command(
2524
};
2625

2726
if !is_team_member {
28-
let cmnt = ErrorComment::new(
29-
&event.issue().unwrap(),
30-
format!("Only Rust team members can ping teams."),
31-
);
32-
cmnt.post(&ctx.github).await?;
33-
return Ok(());
27+
inform!("Only Rust team members can ping teams.");
3428
}
3529

3630
let (gh_team, config) = match config.get_by_name(&team_name.team) {
3731
Some(v) => v,
3832
None => {
39-
let cmnt = ErrorComment::new(
40-
&event.issue().unwrap(),
41-
format!(
42-
"This team (`{}`) cannot be pinged via this command; \
33+
inform!(format!(
34+
"This team (`{}`) cannot be pinged via this command; \
4335
it may need to be added to `triagebot.toml` on the default branch.",
44-
team_name.team,
45-
),
46-
);
47-
cmnt.post(&ctx.github).await?;
48-
return Ok(());
36+
team_name.team,
37+
));
4938
}
5039
};
5140
let team = ctx.team.get_team(&gh_team).await?;
5241
let team = match team {
5342
Some(team) => team,
5443
None => {
55-
let cmnt = ErrorComment::new(
56-
&event.issue().unwrap(),
57-
format!(
58-
"This team (`{}`) does not exist in the team repository.",
59-
team_name.team,
60-
),
61-
);
62-
cmnt.post(&ctx.github).await?;
63-
return Ok(());
44+
inform!(format!(
45+
"This team (`{}`) does not exist in the team repository.",
46+
team_name.team,
47+
));
6448
}
6549
};
6650

@@ -76,11 +60,7 @@ pub(super) async fn handle_command(
7660
)
7761
.await
7862
{
79-
let cmnt = ErrorComment::new(
80-
&event.issue().unwrap(),
81-
format!("Error adding team label (`{}`): {:?}.", label, err),
82-
);
83-
cmnt.post(&ctx.github).await?;
63+
inform!(format!("Error adding team label (`{}`): {:?}.", label, err));
8464
}
8565
}
8666

src/handlers/relabel.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use crate::{
1717
github::UnknownLabels,
1818
github::{self, Event},
1919
handlers::Context,
20-
interactions::ErrorComment,
2120
};
2221
use parser::command::relabel::{LabelDelta, RelabelCommand};
2322

@@ -28,7 +27,7 @@ pub(super) async fn handle_command(
2827
input: RelabelCommand,
2928
) -> anyhow::Result<()> {
3029
let Some(issue) = event.issue() else {
31-
anyhow::bail!("event is not an issue");
30+
inform!("Can only add and remove labels on an issue");
3231
};
3332

3433
// Check label authorization for the current user
@@ -47,10 +46,9 @@ pub(super) async fn handle_command(
4746
)),
4847
Err(err) => Some(err),
4948
};
50-
if let Some(msg) = err {
51-
let cmnt = ErrorComment::new(issue, msg);
52-
cmnt.post(&ctx.github).await?;
53-
return Ok(());
49+
if let Some(err) = err {
50+
// bail-out and inform the user why
51+
inform!(err);
5452
}
5553
}
5654

src/handlers/shortcut.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use crate::{
77
db::issue_data::IssueData,
88
github::{Event, Label},
99
handlers::Context,
10-
interactions::ErrorComment,
1110
};
1211
use octocrab::models::AuthorAssociation;
1312
use parser::command::shortcut::ShortcutCommand;
@@ -31,10 +30,10 @@ pub(super) async fn handle_command(
3130
let issue = event.issue().unwrap();
3231
// NOTE: if shortcuts available to issues are created, they need to be allowed here
3332
if !issue.is_pr() {
34-
let msg = format!("The \"{:?}\" shortcut only works on pull requests.", input);
35-
let cmnt = ErrorComment::new(&issue, msg);
36-
cmnt.post(&ctx.github).await?;
37-
return Ok(());
33+
inform!(format!(
34+
"The \"{:?}\" shortcut only works on pull requests.",
35+
input
36+
));
3837
}
3938

4039
let issue_labels = issue.labels();

0 commit comments

Comments
 (0)