Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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