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:
googletest
adds support to returnanyhow::Result
from a test and then print thatgoogletest
automatically 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