Skip to content

Commit

Permalink
feat: Allow capturing backtraces from anyhow (#341)
Browse files Browse the repository at this point in the history
This also fixes parsing of backtraces that have both line and column numbers
  • Loading branch information
Swatinem committed Jun 7, 2021
1 parent d7f5f2b commit deb3693
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,10 @@

- The minium supported Rust version was bumped to **1.46.0** due to requirements from dependencies.

**Features**:

- Allow capturing backtraces from anyhow errors.

**Fixes**:

- Honor the `attach_stacktrace` option correctly when capturing errors.
Expand Down
3 changes: 2 additions & 1 deletion sentry-anyhow/Cargo.toml
Expand Up @@ -12,8 +12,9 @@ Sentry integration for anyhow.
edition = "2018"

[dependencies]
sentry-backtrace = { version = "0.22.0", path = "../sentry-backtrace" }
sentry-core = { version = "0.22.0", path = "../sentry-core" }
anyhow = "1.0.30"
anyhow = { version = "1.0.39", features = ["backtrace"] }

[dev-dependencies]
sentry = { version = "0.22.0", path = "../sentry", default-features = false, features = ["test"] }
31 changes: 28 additions & 3 deletions sentry-anyhow/src/lib.rs
Expand Up @@ -64,8 +64,33 @@ pub trait AnyhowHubExt {
}

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

// 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));
}

self.capture_event(event)
}
}

#[test]
fn test_has_backtrace() {
std::env::set_var("RUST_BACKTRACE", "1");

let events = sentry::test::with_captured_events(|| {
capture_anyhow(&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,
});

assert!(found_test_fn);
}
6 changes: 5 additions & 1 deletion sentry-backtrace/src/parse.rs
Expand Up @@ -24,6 +24,7 @@ lazy_static::lazy_static! {
\s+at\s # padded "at" in new line
(?P<path>[^\r\n]+?) # path to source file
(?::(?P<lineno>\d+))? # optional source line
(?::(?P<colno>\d+))? # optional source column
)?
$
"#).unwrap();
Expand All @@ -34,7 +35,7 @@ pub fn parse_stacktrace(bt: &str) -> Option<Stacktrace> {
let mut last_address = None;

let frames = FRAME_RE
.captures_iter(&bt)
.captures_iter(bt)
.map(|captures| {
let abs_path = captures.name("path").map(|m| m.as_str().to_string());
let filename = abs_path.as_ref().map(|p| filename(p).to_string());
Expand Down Expand Up @@ -63,6 +64,9 @@ pub fn parse_stacktrace(bt: &str) -> Option<Stacktrace> {
lineno: captures
.name("lineno")
.map(|x| x.as_str().parse::<u64>().unwrap()),
colno: captures
.name("colno")
.map(|x| x.as_str().parse::<u64>().unwrap()),
..Default::default()
}
})
Expand Down

0 comments on commit deb3693

Please sign in to comment.