Skip to content

Commit

Permalink
exception translators considered even for types deriving from std::ex…
Browse files Browse the repository at this point in the history
…ception, now

- also added docs for exception translators
- updated approvals
  • Loading branch information
philsquared committed Nov 18, 2015
1 parent ed6e912 commit a49f088
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 28 deletions.
10 changes: 10 additions & 0 deletions docs/tostring.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ namespace Catch {
}
```

## Exceptions

By default all exceptions deriving from `std::exception` will be translated to strings by calling the `what()` method. For exception types that do not derive from `std::exception` - or if `what()` does not return a suitable string - use `CATCH_TRANSLATE_EXCEPTION`. This defines a function that takes your exception type, by reference, and returns a string. It can appear anywhere in the code - it doesn't have to be in the same translation unit. For example:

```
CATCH_TRANSLATE_EXCEPTION( MyType& ex ) {
return ex.message();
}
```

---

[Home](Readme.md)
21 changes: 8 additions & 13 deletions include/internal/catch_exception_translator_registry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ namespace Catch {
#ifdef __OBJC__
// In Objective-C try objective-c exceptions first
@try {
throw;
return tryTranslators();
}
@catch (NSException *exception) {
return Catch::toString( [exception description] );
}
#else
throw;
return tryTranslators();
#endif
}
catch( TestFailureException& ) {
Expand All @@ -54,20 +54,15 @@ namespace Catch {
return msg;
}
catch(...) {
return tryTranslators( m_translators.begin() );
return "Unknown exception";
}
}

std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it ) const {
if( it == m_translators.end() )
return "Unknown exception";

try {
return (*it)->translate();
}
catch(...) {
return tryTranslators( it+1 );
}
std::string tryTranslators() const {
if( m_translators.empty() )
throw;
else
return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
}

private:
Expand Down
14 changes: 11 additions & 3 deletions include/internal/catch_interfaces_exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,20 @@
#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED

#include <string>
#include <vector>

#include "catch_interfaces_registry_hub.h"

namespace Catch {

typedef std::string(*exceptionTranslateFunction)();

struct IExceptionTranslator;
typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;

struct IExceptionTranslator {
virtual ~IExceptionTranslator();
virtual std::string translate() const = 0;
virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
};

struct IExceptionTranslatorRegistry {
Expand All @@ -35,9 +40,12 @@ namespace Catch {
: m_translateFunction( translateFunction )
{}

virtual std::string translate() const {
virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
try {
throw;
if( it == itEnd )
throw;
else
return (*it)->translate( it+1, itEnd );
}
catch( T& ex ) {
return m_translateFunction( ex );
Expand Down
16 changes: 13 additions & 3 deletions projects/SelfTest/Baselines/console.std.approved.txt
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ due to unexpected exception with message:
expected exception

-------------------------------------------------------------------------------
Unexpected custom exceptions can be translated
Non-std exceptions can be translated
-------------------------------------------------------------------------------
ExceptionTests.cpp:<line number>
...............................................................................
Expand All @@ -365,6 +365,16 @@ ExceptionTests.cpp:<line number>: FAILED:
due to unexpected exception with message:
custom exception

-------------------------------------------------------------------------------
Custom std-exceptions can be custom translated
-------------------------------------------------------------------------------
ExceptionTests.cpp:<line number>
...............................................................................

ExceptionTests.cpp:<line number>: FAILED:
due to unexpected exception with message:
custom std exception

-------------------------------------------------------------------------------
Custom exceptions can be translated when testing for nothrow
-------------------------------------------------------------------------------
Expand Down Expand Up @@ -820,6 +830,6 @@ with expansion:
"first" == "second"

===============================================================================
test cases: 165 | 123 passed | 41 failed | 1 failed as expected
assertions: 912 | 817 passed | 82 failed | 13 failed as expected
test cases: 166 | 123 passed | 42 failed | 1 failed as expected
assertions: 913 | 817 passed | 83 failed | 13 failed as expected

16 changes: 13 additions & 3 deletions projects/SelfTest/Baselines/console.sw.approved.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,7 @@ due to unexpected exception with message:
expected exception

-------------------------------------------------------------------------------
Unexpected custom exceptions can be translated
Non-std exceptions can be translated
-------------------------------------------------------------------------------
ExceptionTests.cpp:<line number>
...............................................................................
Expand All @@ -1226,6 +1226,16 @@ ExceptionTests.cpp:<line number>: FAILED:
due to unexpected exception with message:
custom exception

-------------------------------------------------------------------------------
Custom std-exceptions can be custom translated
-------------------------------------------------------------------------------
ExceptionTests.cpp:<line number>
...............................................................................

ExceptionTests.cpp:<line number>: FAILED:
due to unexpected exception with message:
custom std exception

-------------------------------------------------------------------------------
Custom exceptions can be translated when testing for nothrow
-------------------------------------------------------------------------------
Expand Down Expand Up @@ -9024,6 +9034,6 @@ with expansion:
1 > 0

===============================================================================
test cases: 165 | 122 passed | 42 failed | 1 failed as expected
assertions: 914 | 817 passed | 84 failed | 13 failed as expected
test cases: 166 | 122 passed | 43 failed | 1 failed as expected
assertions: 915 | 817 passed | 85 failed | 13 failed as expected

10 changes: 8 additions & 2 deletions projects/SelfTest/Baselines/junit.sw.approved.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<testsuites>
<testsuite name="CatchSelfTest" errors="12" failures="72" tests="914" hostname="tbd" time="{duration}" timestamp="tbd">
<testsuite name="CatchSelfTest" errors="13" failures="72" tests="915" hostname="tbd" time="{duration}" timestamp="tbd">
<testcase classname="global" name="toString(enum)" time="{duration}"/>
<testcase classname="global" name="toString(enum w/operator&lt;&lt;)" time="{duration}"/>
<testcase classname="global" name="toString(enum class)" time="{duration}"/>
Expand Down Expand Up @@ -226,9 +226,15 @@ expected exception
ExceptionTests.cpp:<line number>
</error>
</testcase>
<testcase classname="global" name="Unexpected custom exceptions can be translated" time="{duration}">
<testcase classname="global" name="Non-std exceptions can be translated" time="{duration}">
<error type="TEST_CASE">
custom exception
ExceptionTests.cpp:<line number>
</error>
</testcase>
<testcase classname="global" name="Custom std-exceptions can be custom translated" time="{duration}">
<error type="TEST_CASE">
custom std exception
ExceptionTests.cpp:<line number>
</error>
</testcase>
Expand Down
12 changes: 9 additions & 3 deletions projects/SelfTest/Baselines/xml.sw.approved.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1545,12 +1545,18 @@
<TestCase name="When unchecked exceptions are thrown, but caught, they do not affect the test">
<OverallResult success="true"/>
</TestCase>
<TestCase name="Unexpected custom exceptions can be translated">
<TestCase name="Non-std exceptions can be translated">
<Exception filename="projects/SelfTest/ExceptionTests.cpp" >
custom exception
</Exception>
<OverallResult success="false"/>
</TestCase>
<TestCase name="Custom std-exceptions can be custom translated">
<Exception filename="projects/SelfTest/ExceptionTests.cpp" >
custom std exception
</Exception>
<OverallResult success="false"/>
</TestCase>
<TestCase name="Custom exceptions can be translated when testing for nothrow">
<Expression success="false" type="REQUIRE_NOTHROW" filename="projects/SelfTest/ExceptionTests.cpp" >
<Original>
Expand Down Expand Up @@ -9496,7 +9502,7 @@ there"
</Section>
<OverallResult success="true"/>
</TestCase>
<OverallResults successes="817" failures="84" expectedFailures="13"/>
<OverallResults successes="817" failures="85" expectedFailures="13"/>
</Group>
<OverallResults successes="817" failures="84" expectedFailures="13"/>
<OverallResults successes="817" failures="85" expectedFailures="13"/>
</Catch>
30 changes: 29 additions & 1 deletion projects/SelfTest/ExceptionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,22 +106,50 @@ class CustomException
std::string m_msg;
};

class CustomStdException : public std::exception
{
public:
CustomStdException( const std::string& msg )
: m_msg( msg )
{}

std::string getMessage() const
{
return m_msg;
}

private:
std::string m_msg;
};


CATCH_TRANSLATE_EXCEPTION( CustomException& ex )
{
return ex.getMessage();
}

CATCH_TRANSLATE_EXCEPTION( CustomStdException& ex )
{
return ex.getMessage();
}

CATCH_TRANSLATE_EXCEPTION( double& ex )
{
return Catch::toString( ex );
}

TEST_CASE("Unexpected custom exceptions can be translated", "[.][failing]" )
TEST_CASE("Non-std exceptions can be translated", "[.][failing]" )
{
if( Catch::alwaysTrue() )
throw CustomException( "custom exception" );
}

TEST_CASE("Custom std-exceptions can be custom translated", "[.][failing]" )
{
if( Catch::alwaysTrue() )
throw CustomException( "custom std exception" );
}

inline void throwCustom() {
if( Catch::alwaysTrue() )
throw CustomException( "custom exception - not std" );
Expand Down

0 comments on commit a49f088

Please sign in to comment.