- 
                Notifications
    
You must be signed in to change notification settings  - Fork 26
 
Description
consider the following code:
#[derive(Debug)]
enum ErrorA {
    Foo,
}
impl std::fmt::Display for ErrorA {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "foo")
    }
}
impl std::error::Error for ErrorA {}
#[derive(Debug)]
enum ErrorB {
    Bar(ErrorA),
}
impl std::fmt::Display for ErrorB {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "bar")
    }
}
impl std::error::Error for ErrorB {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            ErrorB::Bar(e) => Some(e),
        }
    }
}
fn foo() -> Result<(), ErrorB> {
    Err(ErrorB::Bar(ErrorA::Foo))
}
#[cfg(test)]
mod tests {
    use super::*;
    use googletest::prelude::*;
    #[gtest]
    fn test_foo() -> Result<()> {
        foo()?;
        // some googletest assertions here
        Ok(())
    }
}this will just print:
---- foobar::tests::test_foo stdout ----
bar
  at foo/src/bar.rs:42:9
compare this to when anyhow is used:
#[cfg(test)]
mod tests {
    use super::*;
    use anyhow::Context;
    #[test]
    fn test_foo() -> anyhow::Result<()> {
        foo()?;
        // some googletest assertions here
        Ok(())
    }
}where the output is:
Error: bar
Caused by:
    foo
the problem is: googletest is not compatible with anyhow: if you annotate the method with #[gtest] and then return anyhow::Result it doesn't behave as it would without anyhow and thus still doesn't print the "caused by" section.
the same can be observed with the color-eyre library (unsurprising since it's a fork of anyhow).
i see two options:
googletestadds support to returnanyhow::Resultfrom a test and then print thatgoogletestautomatically prints the "caused by" chain if a test method returns something which implementsstd::error::Error
personally i'd vote for the latter as it removes a dependency, should be pretty straight forward (just recurse over the source of the error until it returns None).
this would massively help in understanding nested errors being returned by tests (or rather: functions being called by tests).
note that best practices in rust are that errors either implement source or print the source error in their own message. frameworks like anyhow use source and it seems that a lot of the ecosystem is doing this. see rust-lang/api-guidelines#210 and esp. the thread(s) linked there
note that i have to use #[gtest] because i want/need to use expect_that