failure
failure copied to clipboard
Clarify lack of `backtrace` and `cause` on custom fail types
Maybe its from having come from error-chain where too much magic is happening but I feel the documentation obscures the fact that custom Fails will not have a backtrace or cause.
Two simple ways to improve this
- In "Deriving Fail", rename "Overriding
backtrace" and "Overridingcause" to "Including abacktrace" and "Including acause".- While "overriding" is technically correct, it assumes knowledge of the library.
- In "A Custom Fail Type" provide include commentary about backtrace and cause
I'm personally struggling with how to add context to an Error while retaining the original cause. With error-chain I would just use chain_err.
@euclio The analog to chain_err is context, which does implement cause. What are you worried you're not retaining?
Perhaps I'm not understanding what's going on, but with the following code
extern crate failure;
use failure::{Error, ResultExt};
fn error1() -> Result<(), Error> { Ok(()) }
fn error2() -> Result<(), Error> { Err(failure::err_msg("err")) }
fn run() -> Result<(), Error> {
error1().context("failed because 1")?;
error2().context("failed because 2")?;
Ok(())
}
fn main() {
if let Err(e) = run() {
let mut fail = e.cause();
while let Some(cause) = fail.cause() {
println!("cause: {}", fail);
fail = cause;
}
}
}
I would expect it to print
cause: failed because 2
cause: err
but it only prints
cause: failed because 2
@euclio This looks like a bug in Context's cause method, let me investigate.
@euclio Oh, its actually an error in your while loop logic. Your while loop short circuits when there is no underlying error, meaning it doesn't print the final ("root cause") error. Essentially an off by one error.
Here's one way of writing this loop without the error:
let mut fail = Some(e.cause());
while let Some(cause) = cause {
println!("cause: {}", cause):
fail = cause.cause():
}
Fortunately the 0.1.1 version (hoping to release tomorrow) will have a causes iterator which should make this all simpler:
for cause in e.causes() {
println!("cause: {}", cause):
}
Shouldn't this issue be closed?
It would be nice to rename "Overriding backtrace", this was a tripping point for me.