From 37a0af85a6d2f4b8191e9cf301c291f583dbaf6b Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Thu, 17 Apr 2025 13:19:11 +0200 Subject: [PATCH] Macro to record an HTTP response error with the Sentry event ID attached --- crates/axum-utils/src/sentry.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/crates/axum-utils/src/sentry.rs b/crates/axum-utils/src/sentry.rs index ffa8fac17..5dd00a211 100644 --- a/crates/axum-utils/src/sentry.rs +++ b/crates/axum-utils/src/sentry.rs @@ -13,6 +13,13 @@ use sentry::types::Uuid; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct SentryEventID(Uuid); +impl SentryEventID { + /// Create a new Sentry event ID header for the last event on the hub. + pub fn for_last_event() -> Option { + sentry::last_event_id().map(Self) + } +} + impl From for SentryEventID { fn from(uuid: Uuid) -> Self { Self(uuid) @@ -28,3 +35,28 @@ impl IntoResponseParts for SentryEventID { Ok(res) } } + +/// Record an error. It will emit a tracing event with the error level if +/// matches the pattern, warning otherwise. It also returns the Sentry event ID +/// if the error was recorded. +#[macro_export] +macro_rules! record_error { + ($error:expr, !) => {{ + tracing::warn!(message = &$error as &dyn std::error::Error); + Option::<$crate::sentry::SentryEventID>::None + }}; + + ($error:expr, $pattern:pat) => { + if let $pattern = $error { + tracing::error!(message = &$error as &dyn std::error::Error); + + // With the `sentry-tracing` integration, Sentry should have + // captured an error, so let's extract the last event ID from the + // current hub + $crate::sentry::SentryEventID::for_last_event() + } else { + tracing::warn!(message = &$error as &dyn std::error::Error); + None + } + }; +}