1 /* 2 * Created by Phil on 20/04/2011. 3 * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. 4 * 5 * Distributed under the Boost Software License, Version 1.0. (See accompanying 6 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 */ 8 9 #include "catch_exception_translator_registry.h" 10 #include "catch_assertionhandler.h" 11 #include "catch_compiler_capabilities.h" 12 #include "catch_enforce.h" 13 14 #ifdef __OBJC__ 15 #import "Foundation/Foundation.h" 16 #endif 17 18 namespace Catch { 19 ~ExceptionTranslatorRegistry()20 ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() { 21 } 22 registerTranslator(const IExceptionTranslator * translator)23 void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) { 24 m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) ); 25 } 26 27 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) translateActiveException() const28 std::string ExceptionTranslatorRegistry::translateActiveException() const { 29 try { 30 #ifdef __OBJC__ 31 // In Objective-C try objective-c exceptions first 32 @try { 33 return tryTranslators(); 34 } 35 @catch (NSException *exception) { 36 return Catch::Detail::stringify( [exception description] ); 37 } 38 #else 39 // Compiling a mixed mode project with MSVC means that CLR 40 // exceptions will be caught in (...) as well. However, these 41 // do not fill-in std::current_exception and thus lead to crash 42 // when attempting rethrow. 43 // /EHa switch also causes structured exceptions to be caught 44 // here, but they fill-in current_exception properly, so 45 // at worst the output should be a little weird, instead of 46 // causing a crash. 47 if (std::current_exception() == nullptr) { 48 return "Non C++ exception. Possibly a CLR exception."; 49 } 50 return tryTranslators(); 51 #endif 52 } 53 catch( TestFailureException& ) { 54 std::rethrow_exception(std::current_exception()); 55 } 56 catch( std::exception& ex ) { 57 return ex.what(); 58 } 59 catch( std::string& msg ) { 60 return msg; 61 } 62 catch( const char* msg ) { 63 return msg; 64 } 65 catch(...) { 66 return "Unknown exception"; 67 } 68 } 69 tryTranslators() const70 std::string ExceptionTranslatorRegistry::tryTranslators() const { 71 if (m_translators.empty()) { 72 std::rethrow_exception(std::current_exception()); 73 } else { 74 return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end()); 75 } 76 } 77 78 #else // ^^ Exceptions are enabled // Exceptions are disabled vv translateActiveException() const79 std::string ExceptionTranslatorRegistry::translateActiveException() const { 80 CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!"); 81 } 82 tryTranslators() const83 std::string ExceptionTranslatorRegistry::tryTranslators() const { 84 CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!"); 85 } 86 #endif 87 88 89 } 90