Skip to content

TestAssertionFailure: retain full error chain in message#666

Open
rursprung wants to merge 1 commit intogoogle:mainfrom
rursprung:print-error-chain
Open

TestAssertionFailure: retain full error chain in message#666
rursprung wants to merge 1 commit intogoogle:mainfrom
rursprung:print-error-chain

Conversation

@rursprung
Copy link
Copy Markdown

so far the conversion from an Error to a TestAssertionFailure meant that all information about the source errors were lost. often, the Display implementation for Error implementations does not include the source information since that should instead be retrieved via source. while this has not yet been made into an official API guideline (see rust-lang/api-guidelines#210) this is nevertheless being followed.

various crates like anyhow or eyere take care of pretty-printing the error chain on failure, however this does not work with googletest since googletest::Result has TestAssertionFailure as the error type which swallows any Error and only keeps the message.

to resolve this a simple error chain implementation is added to the From implementation which pretty-prints the error chain.

example:

Error: test3

Caused by:
1: test2
2: test1

fixes #657

}

#[cfg(test)]
mod tests {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you do a bit more testing:

  • Check whether we can / should update the error message verification in test_can_return_anyhow_generated_error() in integration_tests/src/integration_tests.rs

  • Add a new integration test that returns a Result with a custom error type like integration_tests/src/test_returning_anyhow_error.rs

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've added an integration test for it.
i'm not sure what should be updated for anyhow?

@gribozavr
Copy link
Copy Markdown
Collaborator

Thank you for the fix! This PR generally looks good, only a few stylistic comments and a request to add an integration test.

@gribozavr gribozavr assigned gribozavr and rursprung and unassigned gribozavr Aug 20, 2025
TestAssertionFailure::create(format!("{value}"))
// print the full error chain, not just the first error.
let mut description = String::new();
description.push_str(&format!("Error: {value}\n"));
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've removed the explicit Error: here since it's being added elsewhere, here's the output from the integration test when i had Error: present here:

running 1 test
test tests::should_fail_due_to_error_in_subroutine ... FAILED

failures:

---- tests::should_fail_due_to_error_in_subroutine stdout ----
Error: Error: test3

Caused by:
1: test2
2: test1
  at integration_tests\src\test_returning_custom_error.rs:44:9



failures:
    tests::should_fail_due_to_error_in_subroutine

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

i think that's one Error: too many

@rursprung
Copy link
Copy Markdown
Author

sorry that this took so long to update, i've now updated the PR with your feedback. i should be responding (way) faster now

@rursprung rursprung requested a review from gribozavr March 29, 2026 20:16
so far the conversion from an `Error` to a `TestAssertionFailure` meant
that all information about the source errors were lost. often, the
`Display` implementation for `Error` implementations does not include
the source information since that should instead be retrieved via
`source`. while this has not yet been made into an official API
guideline (see [rust-lang/api-guidelines#210]) this is nevertheless
being followed.

various crates like `anyhow` or `eyere` take care of pretty-printing the
error chain on failure, however this does not work with `googletest`
since `googletest::Result` has `TestAssertionFailure` as the error type
which swallows any `Error` and only keeps the message.

to resolve this a simple error chain implementation is added to the
`From` implementation which pretty-prints the error chain.

note that if you use `or_fail` from the `OrFail` trait then you have to
manually convert your `Error` to a `TestAssertionFailure` first as
otherwise you will not profit from this new rendering. this is because
the `OrFail` `impl` is a blanket-impl for all `T: std::fmt::Debug` and
since `std::error::Error` requires `std::fmt::Debug` and specialization
has not yet been stabilised we cannot add a second `impl` for `T:
std::error::Error` where we'd do this conversion.

example:

```
Error: test3

Caused by:
1: test2
2: test1
```

fixes google#657

[rust-lang/api-guidelines#210]: rust-lang/api-guidelines#210
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

#[gtest]: print full error chain if test function returns an error

2 participants