diff --git a/.env.example b/.env.example index 97d2632..9478415 100644 --- a/.env.example +++ b/.env.example @@ -16,3 +16,4 @@ GITEA_TIMEOUT=30 # Optional SENTRY_DSN= RUST_LOG=info +RUST_BACKTRACE=1 diff --git a/Cargo.lock b/Cargo.lock index 2647c1c..f998bb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -786,7 +786,7 @@ checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "herald" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anyhow", "axum", diff --git a/Cargo.toml b/Cargo.toml index 29abeab..2e9845f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,11 @@ [package] name = "herald" -version = "1.0.0" +version = "1.0.1" edition = "2024" +[profile.release] +debug = 1 + [dependencies] reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } tokio = { version = "1.52", features = ["full"] } @@ -12,7 +15,7 @@ futures-util = "0.3" serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } sentry = { version = "0.48", features = ["tower-axum-matched-path"] } -sentry-anyhow = "0.48" +sentry-anyhow = { version = "0.48", features = ["backtrace"] } openrouter-rs = "0.10" dotenvy = "0.15" tower = "0.5" @@ -20,7 +23,7 @@ tower-http = {version = "0.6", features = ["trace"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features=["env-filter"] } axum = "0.8" -anyhow = "1.0" +anyhow = { version = "1.0", features = ["backtrace"] } thiserror = "2.0" hmac = "0.13" sha2 = "0.11" diff --git a/src/bot.rs b/src/bot.rs index 929bb16..22b10c2 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -97,9 +97,15 @@ impl Bot { Ok(()) } - #[instrument(skip(self))] + #[instrument(skip(self, webhook), fields(repo, pr))] pub async fn exec(&self, webhook: WebhookType) { - tracing::Span::current().record("webhook_type", tracing::field::debug(&webhook)); + match &webhook { + WebhookType::Review(p) => { + tracing::Span::current().record("repo", &p.repository.full_name); + tracing::Span::current().record("pr", p.pull_request.number); + } + }; + let exec_result = match webhook { WebhookType::Review(review_payload) => crate::bot_actions::review::exec_review( &self.gitea_api, diff --git a/src/bot_actions/review.rs b/src/bot_actions/review.rs index 88a1d9f..4bf840f 100644 --- a/src/bot_actions/review.rs +++ b/src/bot_actions/review.rs @@ -10,7 +10,7 @@ use crate::{ open_router::OpenRouterClient, }; -#[instrument(skip(gitea_api, open_router_client, http_client, review_payload), err)] +#[instrument(skip(gitea_api, open_router_client, http_client, review_payload))] pub async fn exec_review( gitea_api: &GiteaAPI, open_router_client: &OpenRouterClient, diff --git a/src/env.rs b/src/env.rs index 1d3e862..855b58b 100644 --- a/src/env.rs +++ b/src/env.rs @@ -41,13 +41,13 @@ pub fn load_config() -> anyhow::Result { } pub fn try_get_env(key: &str) -> anyhow::Result { - let env = std::env::var(key)?; + let env_value = std::env::var(key).map_err(|e| anyhow::anyhow!("{}: {}", key, e))?; - if env.trim().is_empty() { + if env_value.trim().is_empty() { return Err(anyhow!(format!("env var {} is empty", key))); } - Ok(env) + Ok(env_value) } #[cfg(test)] diff --git a/src/gitea.rs b/src/gitea.rs index 34fb852..e405ca1 100644 --- a/src/gitea.rs +++ b/src/gitea.rs @@ -29,7 +29,7 @@ impl GiteaAPI { }) } - #[instrument(skip(self), err)] + #[instrument(skip(self))] pub async fn comment( &self, body: &str, @@ -57,7 +57,7 @@ impl GiteaAPI { res.json::().await.map_err(anyhow::Error::from) } - #[instrument(skip(self), err)] + #[instrument(skip(self))] pub async fn edit_comment( &self, body: &str, @@ -85,7 +85,7 @@ impl GiteaAPI { Ok(()) } - #[instrument(skip(self), err)] + #[instrument(skip(self))] pub async fn delete_comment(&self, full_name: &str, comment_id: u64) -> anyhow::Result<()> { let url = format!( "{}/api/v1/repos/{}/issues/comments/{}", @@ -104,7 +104,7 @@ impl GiteaAPI { Ok(()) } - #[instrument(skip(self, review_result), err)] + #[instrument(skip(self, review_result))] pub async fn post_pull_request_review( &self, review_result: &ReviewResult, @@ -206,14 +206,6 @@ impl WebhookType { _ => Err(AppError::UnknownEventErr), }?; - let pr_body = match &wb { - WebhookType::Review(review_payload) => &review_payload.comment.body, - }; - - if !pr_body.starts_with(&format!("@{}", bot_name)) { - return Err(AppError::UnauthorizedUserErr); - } - let action = match &wb { WebhookType::Review(review_payload) => &review_payload.action, }; @@ -222,6 +214,14 @@ impl WebhookType { return Err(AppError::InvalidActionErr); } + let pr_body = match &wb { + WebhookType::Review(review_payload) => &review_payload.comment.body, + }; + + if !pr_body.starts_with(&format!("@{}", bot_name)) { + return Err(AppError::UnauthorizedUserErr); + } + Ok(wb) } }