Skip to content

Commit fefe0e7

Browse files
committed
Comment on issues when @rustbot label is given an invalid label
Previously, the label was just silently ignored, along with all other labels in the same command. This tells the user what went wrong, and also adds all valid labels
1 parent daaf943 commit fefe0e7

File tree

3 files changed

+55
-11
lines changed

3 files changed

+55
-11
lines changed

src/github.rs

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -366,17 +366,36 @@ impl IssueRepository {
366366
)
367367
}
368368

369-
async fn has_label(&self, client: &GithubClient, label: &str) -> bool {
369+
async fn has_label(&self, client: &GithubClient, label: &str) -> anyhow::Result<bool> {
370370
#[allow(clippy::redundant_pattern_matching)]
371371
let url = format!("{}/labels/{}", self.url(), label);
372-
match client.send_req(client.get(&url)).await {
373-
Ok(_) => true,
374-
// XXX: Error handling if the request failed for reasons beyond 'label didn't exist'
375-
Err(_) => false,
372+
match client._send_req(client.get(&url)).await {
373+
Ok((_, _)) => Ok(true),
374+
Err(e) => {
375+
if e.downcast_ref::<reqwest::Error>().map_or(false, |e| e.status() == Some(StatusCode::NOT_FOUND)) {
376+
Ok(false)
377+
} else {
378+
Err(e)
379+
}
380+
}
376381
}
377382
}
378383
}
379384

385+
#[derive(Debug)]
386+
pub(crate) struct UnknownLabels {
387+
labels: Vec<String>,
388+
}
389+
390+
impl fmt::Display for UnknownLabels {
391+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
392+
f.write_str("Unknown labels:\n- ")?;
393+
write!(f, "{}", &self.labels.join("\n- "))
394+
}
395+
}
396+
397+
impl std::error::Error for UnknownLabels {}
398+
380399
impl Issue {
381400
pub fn to_zulip_github_reference(&self) -> ZulipGitHubReference {
382401
ZulipGitHubReference {
@@ -519,18 +538,27 @@ impl Issue {
519538
return Ok(());
520539
}
521540

522-
for label in &labels {
523-
if !self.repository().has_label(client, &label).await {
524-
anyhow::bail!("Label {} does not exist in {}", label, self.global_id());
541+
let mut unknown_labels = vec![];
542+
let mut known_labels = vec![];
543+
for label in labels {
544+
if !self.repository().has_label(client, &label).await? {
545+
unknown_labels.push(label);
546+
} else {
547+
known_labels.push(label);
525548
}
526549
}
527550

551+
if !unknown_labels.is_empty() {
552+
return Err(UnknownLabels { labels: unknown_labels }.into());
553+
}
554+
528555
#[derive(serde::Serialize)]
529556
struct LabelsReq {
530557
labels: Vec<String>,
531558
}
559+
532560
client
533-
._send_req(client.post(&url).json(&LabelsReq { labels }))
561+
._send_req(client.post(&url).json(&LabelsReq { labels: known_labels }))
534562
.await
535563
.context("failed to add labels")?;
536564

@@ -1382,6 +1410,12 @@ pub trait IssuesQuery {
13821410
mod tests {
13831411
use super::*;
13841412

1413+
#[test]
1414+
fn display_labels() {
1415+
let x = UnknownLabels { labels: vec!["A-bootstrap".into(), "xxx".into()] };
1416+
assert_eq!(x.to_string(), "Unknown labels:\n- A-bootstrap\n- xxx");
1417+
}
1418+
13851419
#[test]
13861420
fn extract_one_file() {
13871421
let input = r##"\

src/handlers/autolabel.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,18 @@ pub(super) async fn handle_input(
125125
event: &IssuesEvent,
126126
input: AutolabelInput,
127127
) -> anyhow::Result<()> {
128-
event.issue.add_labels(&ctx.github, input.add).await?;
128+
match event.issue.add_labels(&ctx.github, input.add).await {
129+
Ok(()) => {}
130+
Err(e) => {
131+
use crate::github::UnknownLabels;
132+
if let Some(err @ UnknownLabels{ .. }) = e.downcast_ref() {
133+
event.issue.post_comment(&ctx.github, &err.to_string()).await.context("failed to post missing label comment")?;
134+
return Ok(());
135+
}
136+
return Err(e);
137+
}
138+
}
139+
129140
for label in input.remove {
130141
event
131142
.issue

src/interactions.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::github::{GithubClient, Issue};
22
use std::fmt::Write;
3-
use tracing as log;
43

54
pub struct ErrorComment<'a> {
65
issue: &'a Issue,

0 commit comments

Comments
 (0)