You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
You get different behavior when trying to access the backtrace of an error behind an enum.
When the enum value is derived with from , without specifying an own backtrace member (as tuple)
the backtrace() api call from the Error trait will return None
When the enum value has an own backtrace member, the backtrace() api call will return the backtrace of the underlying error.
Accessing the backtrace value of the enum value is not possible anymore.
From my POV the best way would be that the backtrace() api call should always return the uppermost backtrace if it is specified. Because it would be still possible to use the source() api call to get to the inner error.
Is the current behavior a bug or expected ?
Thanks,
Peter
Putting the code example here as reference also:
#![feature(backtrace)]
#![feature(backtrace_frames)]
use std::{backtrace::Backtrace, error::Error};
use thiserror::Error as ThisError;
#[derive(ThisError, Debug)]
#[error("MyError")]
struct MyError {
backtrace: std::backtrace::Backtrace,
}
#[derive(ThisError, Debug)]
#[error("OtherError")]
struct OtherError {
backtrace: std::backtrace::Backtrace,
}
#[derive(ThisError, Debug)]
enum AllErrors {
#[error("E")]
E(#[from] MyError),
#[error("O")]
O(#[from] OtherError, Backtrace),
}
fn main() {
let my = MyError {
backtrace: std::backtrace::Backtrace::capture(), // Backtrace location A
};
assert!(my.backtrace().is_some());
let other = OtherError {
backtrace: std::backtrace::Backtrace::capture(), // Backtrace location B
};
assert!(other.backtrace().is_some());
let all_my = AllErrors::from(my);
let all_other = AllErrors::from(other); // Implicit Backtrace C
println!("My my {:#?}", all_my.backtrace()); // -> None
println!("My my source {:#?}", all_my.source().unwrap().backtrace()); // -> Backtrace A
println!("Other my {:#?}", all_other.backtrace()); // -> Backtrace B
println!(
"Other my source {:#?}",
all_other.source().unwrap().backtrace() // Backtrace B
);
// Inconsistency:
// Option 1 : Always return inner backtrace
// all_my.backtrace() should return Backtrace A
// all_other.backtrace() should return Backtrace B // as
// Option 2: Always deliver own backtrace
// all_my.backtrace() should return None
// all_other.backtrace() should return Backtrace C ( where all_other was created )
// The prefered option is Option 2 as currently there is no way to access backtrace C
// using the backtrace interface
}
The text was updated successfully, but these errors were encountered:
Hi,
I discovered a little strange behavior when using the experimental backtrace api together with thiserror.
I have prepared an example gist and the playground
You get different behavior when trying to access the backtrace of an error behind an enum.
When the enum value is derived with from , without specifying an own backtrace member (as tuple)
the backtrace() api call from the Error trait will return None
When the enum value has an own backtrace member, the backtrace() api call will return the backtrace of the underlying error.
Accessing the backtrace value of the enum value is not possible anymore.
From my POV the best way would be that the backtrace() api call should always return the uppermost backtrace if it is specified. Because it would be still possible to use the source() api call to get to the inner error.
Is the current behavior a bug or expected ?
Thanks,
Peter
Putting the code example here as reference also:
The text was updated successfully, but these errors were encountered: