Skip to content

Commit

Permalink
ref(anyhow): Extract public event_from_error fn (#476)
Browse files Browse the repository at this point in the history
* ref(anyhow): Extract public event_from_error fn
  • Loading branch information
kamilogorek committed Jun 23, 2022
1 parent bdafb2f commit 0112a4e
Showing 1 changed file with 53 additions and 27 deletions.
80 changes: 53 additions & 27 deletions sentry-anyhow/src/lib.rs
Expand Up @@ -41,6 +41,7 @@
#![warn(missing_docs)]
#![deny(unsafe_code)]

use sentry_core::protocol::Event;
use sentry_core::types::Uuid;
use sentry_core::Hub;

Expand All @@ -58,6 +59,26 @@ pub fn capture_anyhow(e: &anyhow::Error) -> Uuid {
Hub::with_active(|hub| hub.capture_anyhow(e))
}

/// Helper function to create an event from a `anyhow::Error`.
pub fn event_from_error(err: &anyhow::Error) -> Event<'static> {
let dyn_err: &dyn std::error::Error = err.as_ref();

// It's not mutated for not(feature = "backtrace")
#[allow(unused_mut)]
let mut event = sentry_core::event_from_error(dyn_err);

#[cfg(feature = "backtrace")]
{
// exception records are sorted in reverse
if let Some(exc) = event.exception.iter_mut().last() {
let backtrace = err.backtrace();
exc.stacktrace = sentry_backtrace::parse_stacktrace(&format!("{:#}", backtrace));
}
}

event
}

/// Hub extension methods for working with [`anyhow`].
pub trait AnyhowHubExt {
/// Captures an [`anyhow::Error`] on a specific hub.
Expand All @@ -66,39 +87,44 @@ pub trait AnyhowHubExt {

impl AnyhowHubExt for Hub {
fn capture_anyhow(&self, anyhow_error: &anyhow::Error) -> Uuid {
let dyn_err: &dyn std::error::Error = anyhow_error.as_ref();
let event = event_from_error(anyhow_error);
self.capture_event(event)
}
}

#[cfg(all(feature = "backtrace", test))]
mod tests {
use super::*;

#[cfg(feature = "backtrace")]
{
let mut event = sentry_core::event_from_error(dyn_err);
#[test]
fn test_event_from_error_with_backtrace() {
std::env::set_var("RUST_BACKTRACE", "1");

// exception records are sorted in reverse
if let Some(exc) = event.exception.iter_mut().last() {
let backtrace = anyhow_error.backtrace();
exc.stacktrace = sentry_backtrace::parse_stacktrace(&format!("{:#}", backtrace));
}
let event = event_from_error(&anyhow::anyhow!("Oh jeez"));

self.capture_event(event)
}
#[cfg(not(feature = "backtrace"))]
self.capture_error(dyn_err)
let stacktrace = event.exception[0].stacktrace.as_ref().unwrap();
let found_test_fn = stacktrace
.frames
.iter()
.find(|frame| match &frame.function {
Some(f) => f.contains("test_event_from_error_with_backtrace"),
None => false,
});

assert!(found_test_fn.is_some());
}
}

#[cfg(all(feature = "backtrace", test))]
#[test]
fn test_has_backtrace() {
std::env::set_var("RUST_BACKTRACE", "1");
#[test]
fn test_capture_anyhow_uses_event_from_error_helper() {
std::env::set_var("RUST_BACKTRACE", "1");

let events = sentry::test::with_captured_events(|| {
capture_anyhow(&anyhow::anyhow!("Oh jeez"));
});
let err = &anyhow::anyhow!("Oh jeez");

let stacktrace = events[0].exception[0].stacktrace.as_ref().unwrap();
let found_test_fn = stacktrace.frames.iter().any(|frame| match &frame.function {
Some(f) => f.contains("test_has_backtrace"),
None => false,
});
let event = event_from_error(err);
let events = sentry::test::with_captured_events(|| {
capture_anyhow(err);
});

assert!(found_test_fn);
assert_eq!(event.exception, events[0].exception);
}
}

0 comments on commit 0112a4e

Please sign in to comment.