Skip to content

Commit

Permalink
feat: add error hook (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
backwardspy authored Sep 22, 2024
1 parent a7e4c94 commit 98070a5
Show file tree
Hide file tree
Showing 16 changed files with 489 additions and 200 deletions.
55 changes: 44 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,17 @@ cargo = "warn"

[dependencies]
anyhow = "1.0.86"
axum = "0.7.5"
axum = "0.7.6"
axum-github-webhook-extract = "0.2.0"
catppuccin = "2.4.0"
envy = "0.4.2"
octocrab = { git = "https://github.com/backwardspy/octocrab", branch = "feat/webhook-model-fields" }
reqwest = { version = "0.12.4", features = ["json"] }
serde = "1.0.203"
serde_json = "1.0.117"
thiserror = "1.0.63"
tokio = { version = "1.38.0", features = ["full"] }
tower-http = { version = "0.5.2", features = ["trace"] }
tower-http = { version = "0.6.0", features = ["trace"] }
tracing = "0.1.40"
tracing-subscriber = "0.3.18"

Expand Down
21 changes: 17 additions & 4 deletions src/embed_builder.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use octocrab::models::Author;
use serde_json::json;
use thiserror::Error;

const MAX_TITLE_LENGTH: usize = 100;
const MAX_DESCRIPTION_LENGTH: usize = 640;
Expand All @@ -14,6 +15,18 @@ pub struct EmbedBuilder {
color: Option<u32>,
}

#[derive(Debug, Error)]
pub enum Error {
#[error("missing title")]
Title,
#[error("missing url")]
Url,
#[error("missing author")]
Author,
}

pub type Result<T> = std::result::Result<T, Error>;

impl EmbedBuilder {
pub fn title(&mut self, title: &str) -> &Self {
self.title = Some(limit_text_length(title, MAX_TITLE_LENGTH));
Expand Down Expand Up @@ -41,14 +54,14 @@ impl EmbedBuilder {
self
}

pub fn try_build(self) -> anyhow::Result<serde_json::Value> {
pub fn try_build(self) -> Result<serde_json::Value> {
Ok(json!({
"embeds": [{
"title": self.title.ok_or_else(|| anyhow::anyhow!("missing title"))?,
"url": self.url.ok_or_else(|| anyhow::anyhow!("missing url"))?,
"title": self.title.ok_or(Error::Title)?,
"url": self.url.ok_or(Error::Url)?,
"description": self.description,
"color": self.color,
"author": embed_author(&self.author.ok_or_else(|| anyhow::anyhow!("missing author"))?),
"author": embed_author(&self.author.ok_or(Error::Author)?),
}],
}))
}
Expand Down
24 changes: 24 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use octocrab::models::webhook_events::WebhookEventType;
use thiserror::Error;

use crate::embed_builder;

#[derive(Debug, Error)]
pub enum RockdoveError {
#[error("missing field in event: {event_type:?}::{field}")]
MissingField {
event_type: WebhookEventType,
field: &'static str,
},

#[error("invalid field in event: {event_type:?}::{field}")]
InvalidField {
event_type: WebhookEventType,
field: &'static str,
},

#[error(transparent)]
EmbedBuilder(#[from] embed_builder::Error),
}

pub type RockdoveResult<T> = Result<T, RockdoveError>;
70 changes: 60 additions & 10 deletions src/events.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,60 @@
pub mod commit_comment;
pub mod discussion;
pub mod discussion_comment;
pub mod issue_comment;
pub mod issues;
pub mod membership;
pub mod pull_request;
pub mod pull_request_review;
pub mod release;
pub mod repository;
use octocrab::models::webhook_events::{WebhookEvent, WebhookEventPayload};
use tracing::info;

use crate::{
embed_builder::EmbedBuilder,
errors::{RockdoveError, RockdoveResult},
};

mod commit_comment;
mod discussion;
mod discussion_comment;
mod issue_comment;
mod issues;
mod membership;
mod pull_request;
mod pull_request_review;
mod release;
mod repository;

pub fn make_embed(event: WebhookEvent) -> RockdoveResult<Option<serde_json::Value>> {
let sender = event
.sender
.clone()
.ok_or_else(|| RockdoveError::MissingField {
event_type: event.kind.clone(),
field: "sender",
})?;

let Some(mut embed) = begin_embed(event)? else {
info!("ignoring event");
return Ok(None);
};

embed.author(sender);
Ok(Some(embed.try_build()?))
}

fn begin_embed(event: WebhookEvent) -> RockdoveResult<Option<EmbedBuilder>> {
match event.specific.clone() {
WebhookEventPayload::Repository(specifics) => repository::make_embed(event, &specifics),
WebhookEventPayload::Discussion(specifics) => discussion::make_embed(event, &specifics),
WebhookEventPayload::DiscussionComment(specifics) => {
discussion_comment::make_embed(event, &specifics)
}
WebhookEventPayload::Issues(specifics) => issues::make_embed(event, &specifics),
WebhookEventPayload::PullRequest(specifics) => pull_request::make_embed(event, &specifics),
WebhookEventPayload::IssueComment(specifics) => {
issue_comment::make_embed(event, &specifics)
}
WebhookEventPayload::CommitComment(specifics) => {
commit_comment::make_embed(event, &specifics)
}
WebhookEventPayload::PullRequestReview(specifics) => {
pull_request_review::make_embed(event, &specifics)
}
WebhookEventPayload::Release(specifics) => release::make_embed(event, &specifics),
WebhookEventPayload::Membership(specifics) => membership::make_embed(event, &specifics),
_ => Ok(None),
}
}
24 changes: 17 additions & 7 deletions src/events/commit_comment.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
use octocrab::models::webhook_events::{payload::CommitCommentWebhookEventPayload, WebhookEvent};

use crate::{colors::COMMIT_COLOR, embed_builder::EmbedBuilder};
use crate::{
colors::COMMIT_COLOR,
embed_builder::EmbedBuilder,
errors::{RockdoveError, RockdoveResult},
};

pub fn make_commit_comment_embed(
pub fn make_embed(
event: WebhookEvent,
specifics: &CommitCommentWebhookEventPayload,
) -> EmbedBuilder {
) -> RockdoveResult<Option<EmbedBuilder>> {
let repo = event
.repository
.expect("commit comment events should always have a repository");
.ok_or_else(|| RockdoveError::MissingField {
event_type: event.kind.clone(),
field: "repository",
})?;

let mut embed = EmbedBuilder::default();

Expand All @@ -24,18 +31,21 @@ pub fn make_commit_comment_embed(
.comment
.body
.as_ref()
.expect("commit comment should always have a body")
.ok_or_else(|| RockdoveError::MissingField {
event_type: event.kind.clone(),
field: "comment.body",
})?
.as_str(),
);
embed.color(COMMIT_COLOR);

embed
Ok(Some(embed))
}

#[cfg(test)]
mod tests {
use crate::{
make_embed,
events::make_embed,
tests::{embed_context, TestConfig},
};

Expand Down
Loading

0 comments on commit 98070a5

Please sign in to comment.