mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-11-04 05:59:32 +01:00 
			
		
		
		
	Improved custom exception handling
This commit is contained in:
		@@ -79,19 +79,33 @@ private:
 | 
			
		||||
    std::string m_msg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Catch
 | 
			
		||||
CATCH_TRANSLATE_EXCEPTION( CustomException& ex )
 | 
			
		||||
{
 | 
			
		||||
    ExceptionTranslator<CustomException> translator;
 | 
			
		||||
 | 
			
		||||
    template<>
 | 
			
		||||
    std::string ExceptionTranslator<CustomException>::translate( CustomException& ex ) const
 | 
			
		||||
    {
 | 
			
		||||
        return ex.getMessage();
 | 
			
		||||
    }
 | 
			
		||||
    return ex.getMessage();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_CASE_NORETURN( "./succeeding/exceptions/custom", "" )
 | 
			
		||||
CATCH_TRANSLATE_EXCEPTION( double& ex )
 | 
			
		||||
{
 | 
			
		||||
    return Catch::toString( ex );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_CASE_NORETURN( "./failing/exceptions/custom", "Unexpected custom exceptions can be translated" )
 | 
			
		||||
{
 | 
			
		||||
    throw CustomException( "custom exception" );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_CASE( "./failing/exceptions/custom/nothrow", "Custom exceptions can be translated when testing for nothrow" )
 | 
			
		||||
{
 | 
			
		||||
    REQUIRE_NOTHROW( throw CustomException( "unexpected custom exception" ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_CASE( "./failing/exceptions/custom/throw", "Custom exceptions can be translated when testing for throwing as something else" )
 | 
			
		||||
{
 | 
			
		||||
    REQUIRE_THROWS_AS( throw CustomException( "custom exception - not std" ), std::exception );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TEST_CASE_NORETURN( "./failing/exceptions/custom/double", "Unexpected custom exceptions can be translated"  )
 | 
			
		||||
{
 | 
			
		||||
    throw double( 3.14 );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -60,6 +60,7 @@
 | 
			
		||||
#define METHOD_AS_TEST_CASE( method, name, description ) CATCH_METHOD_AS_TEST_CASE( method, name, description )
 | 
			
		||||
 | 
			
		||||
#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
 | 
			
		||||
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
 | 
			
		||||
 | 
			
		||||
#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -735,7 +735,7 @@ inline bool isTrue
 | 
			
		||||
    } \
 | 
			
		||||
    catch( ... ) \
 | 
			
		||||
    { \
 | 
			
		||||
        INTERNAL_CATCH_ACCEPT_EXPR( Catch::ResultBuilder( __FILE__, __LINE__, macroName, #expr ).setResultType( Catch::ResultWas::ThrewException ), stopOnFailure ); \
 | 
			
		||||
        INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ResultBuilder( __FILE__, __LINE__, macroName, #expr ) << Catch::Hub::getExceptionTranslatorRegistry().translateActiveException() ).setResultType( Catch::ResultWas::ThrewException ), stopOnFailure ); \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -759,7 +759,7 @@ inline bool isTrue
 | 
			
		||||
    INTERNAL_CATCH_THROWS( expr, exceptionType, stopOnFailure, macroName ) \
 | 
			
		||||
    catch( ... ) \
 | 
			
		||||
    { \
 | 
			
		||||
        INTERNAL_CATCH_ACCEPT_EXPR( Catch::ResultBuilder( __FILE__, __LINE__, macroName, #expr ).setResultType( Catch::ResultWas::ThrewException ), stopOnFailure ); \
 | 
			
		||||
        INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ResultBuilder( __FILE__, __LINE__, macroName, #expr ) << Catch::Hub::getExceptionTranslatorRegistry().translateActiveException() ).setResultType( Catch::ResultWas::ThrewException ), stopOnFailure ); \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -38,30 +38,55 @@ namespace Catch
 | 
			
		||||
        
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    class ExceptionTranslator : public IExceptionTranslator
 | 
			
		||||
    class ExceptionTranslatorRegistrar
 | 
			
		||||
    {
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        class ExceptionTranslator : public IExceptionTranslator
 | 
			
		||||
        {
 | 
			
		||||
        public:
 | 
			
		||||
            
 | 
			
		||||
            ExceptionTranslator
 | 
			
		||||
            (
 | 
			
		||||
                std::string(*translateFunction)( T& ) 
 | 
			
		||||
            )
 | 
			
		||||
            : m_translateFunction( translateFunction )
 | 
			
		||||
            {}
 | 
			
		||||
            
 | 
			
		||||
            virtual std::string translate
 | 
			
		||||
            ()
 | 
			
		||||
            const
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    throw;
 | 
			
		||||
                }
 | 
			
		||||
                catch( T& ex )
 | 
			
		||||
                {
 | 
			
		||||
                    return m_translateFunction( ex );
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
        protected:
 | 
			
		||||
            std::string(*m_translateFunction)( T& );
 | 
			
		||||
        };
 | 
			
		||||
        
 | 
			
		||||
    public:
 | 
			
		||||
        ExceptionTranslator()
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        ExceptionTranslatorRegistrar
 | 
			
		||||
        (
 | 
			
		||||
            std::string(*translateFunction)( T& ) 
 | 
			
		||||
        )
 | 
			
		||||
        {
 | 
			
		||||
            Catch::Hub::getExceptionTranslatorRegistry().registerTranslator( this );
 | 
			
		||||
            Catch::Hub::getExceptionTranslatorRegistry().registerTranslator
 | 
			
		||||
                ( new ExceptionTranslator<T>( translateFunction ) );
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        virtual std::string translate() const
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                throw;
 | 
			
		||||
            }
 | 
			
		||||
            catch( T& ex )
 | 
			
		||||
            {
 | 
			
		||||
                return translate( ex );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
    protected:
 | 
			
		||||
        std::string translate( T& ex ) const;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
 | 
			
		||||
    static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
 | 
			
		||||
    namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
 | 
			
		||||
    static std::string INTERNAL_CATCH_UNIQUE_NAME(  catch_internal_ExceptionTranslator )( signature )
 | 
			
		||||
 | 
			
		||||
#endif // TWOBLUECUBES_CATCH_INTERFACES_EXCEPTIONS_H_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user