Catch exceptions from StringMakers inside Detail::stringify

This stops tests failing falsely if the assertion passed, but the
stringification itself failed as the assertion was sent to the reporter.

I don't think that stringification should be fallible, but the
overhead in compilation ended up being small enough (<0.5% on `SelfTest`)
that it might be worth implementing, in case there is more users
with weird `StringMaker`s than just MongoDB.

Closes #2980
This commit is contained in:
Martin Hořeňovský
2025-08-01 23:23:34 +02:00
parent 17fe5eaa5c
commit c5e0ef4e67
20 changed files with 129 additions and 20 deletions

View File

@@ -8,6 +8,7 @@
#include <catch2/catch_tostring.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_context.hpp>
#include <catch2/internal/catch_polyfills.hpp>
@@ -113,6 +114,15 @@ namespace Detail {
rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
return rss.str();
}
std::string makeExceptionHappenedString() {
return "{ stringification failed with an exception: \"" +
translateActiveException() + "\" }";
}
} // end Detail namespace

View File

@@ -139,11 +139,17 @@ namespace Catch {
namespace Detail {
std::string makeExceptionHappenedString();
// This function dispatches all stringification requests inside of Catch.
// Should be preferably called fully qualified, like ::Catch::Detail::stringify
template <typename T>
std::string stringify(const T& e) {
return ::Catch::StringMaker<std::remove_cv_t<std::remove_reference_t<T>>>::convert(e);
std::string stringify( const T& e ) {
CATCH_TRY {
return ::Catch::StringMaker<
std::remove_cv_t<std::remove_reference_t<T>>>::convert( e );
}
CATCH_CATCH_ALL { return makeExceptionHappenedString(); }
}
template<typename E>