diff --git a/src/coreComponents/codingUtilities/Parsing.hpp b/src/coreComponents/codingUtilities/Parsing.hpp index 3badd24f056..7acd766cfb5 100644 --- a/src/coreComponents/codingUtilities/Parsing.hpp +++ b/src/coreComponents/codingUtilities/Parsing.hpp @@ -91,7 +91,7 @@ char const * parseBuffer( char const * first, * @param issep function that returns true if given character is a value separator * @return @p last if the entire buffer has been processed, or pointer to * the start of the unprocessed part if a parsing error occurred - * @throws std::runtime_error if file IO or parsing error occurred + * @throws geos::RuntimeError if file IO or parsing error occurred */ template< typename CONTAINER, typename SEPFUNC > void parseFile( string const & filename, @@ -134,13 +134,13 @@ void parseFile( string const & filename, GEOS_THROW( GEOS_FMT( "Unable to parse value in file {} at position {}: {}...", filename, static_cast< std::streamoff >( inputStream.tellg() ) - left, string( ptr, std::min( left, std::ptrdiff_t{32} ) ) ), - std::runtime_error ); + geos::RuntimeError ); } } GEOS_THROW_IF( inputStream.fail() && !inputStream.eof(), GEOS_FMT( "Error while reading file {}: {}", filename, std::strerror( errno ) ), - std::runtime_error ); + geos::RuntimeError ); } } // namespace geos diff --git a/src/coreComponents/codingUtilities/tests/testParsing.cpp b/src/coreComponents/codingUtilities/tests/testParsing.cpp index 6d9e7b3ae04..e045979730a 100644 --- a/src/coreComponents/codingUtilities/tests/testParsing.cpp +++ b/src/coreComponents/codingUtilities/tests/testParsing.cpp @@ -140,7 +140,7 @@ class ParsingTest : public ::testing::TestWithParam< T > geos::stdVector< T > vec; auto const issep_invalid = []( char const c ){ return c == '|'; }; - EXPECT_THROW( geos::parseFile( fname, vec, issep_invalid ), std::runtime_error ); + EXPECT_THROW( geos::parseFile( fname, vec, issep_invalid ), geos::RuntimeError ); std::remove( fname.c_str() ); } diff --git a/src/coreComponents/common/CMakeLists.txt b/src/coreComponents/common/CMakeLists.txt index 2b094d68ad2..38d684c29bd 100644 --- a/src/coreComponents/common/CMakeLists.txt +++ b/src/coreComponents/common/CMakeLists.txt @@ -38,6 +38,7 @@ set( common_headers GEOS_RAJA_Interface.hpp GeosxMacros.hpp MemoryInfos.hpp + logger/GeosExceptions.hpp logger/Logger.hpp logger/ErrorHandling.hpp logger/ExternalErrorHandler.hpp diff --git a/src/coreComponents/common/Path.cpp b/src/coreComponents/common/Path.cpp index b376b1580b2..11ac6e3d679 100644 --- a/src/coreComponents/common/Path.cpp +++ b/src/coreComponents/common/Path.cpp @@ -140,7 +140,7 @@ void makeDirectory( std::string const & path ) { constexpr mode_t mode = 0770; // user and group rwx permissions int const err = mkdir( path.c_str(), mode ); - GEOS_THROW_IF( err && ( errno != EEXIST ), "Failed to create directory: " << path, std::runtime_error ); + GEOS_THROW_IF( err && ( errno != EEXIST ), "Failed to create directory: " << path, geos::RuntimeError ); } void makeDirsForPath( std::string const & path ) diff --git a/src/coreComponents/common/format/table/TableLayout.hpp b/src/coreComponents/common/format/table/TableLayout.hpp index b166f65b198..4ef156ad760 100644 --- a/src/coreComponents/common/format/table/TableLayout.hpp +++ b/src/coreComponents/common/format/table/TableLayout.hpp @@ -20,10 +20,8 @@ #ifndef GEOS_COMMON_FORMAT_TABLE_TABLELAYOUT_HPP #define GEOS_COMMON_FORMAT_TABLE_TABLELAYOUT_HPP -#include "common/DataTypes.hpp" #include "TableTypes.hpp" #include -#include "common/logger/Logger.hpp" namespace geos diff --git a/src/coreComponents/common/format/table/TableTypes.hpp b/src/coreComponents/common/format/table/TableTypes.hpp index 4565ad92ff8..59826ddde6a 100644 --- a/src/coreComponents/common/format/table/TableTypes.hpp +++ b/src/coreComponents/common/format/table/TableTypes.hpp @@ -23,6 +23,8 @@ #ifndef GEOS_COMMON_FORMAT_TABLETYPES_HPP #define GEOS_COMMON_FORMAT_TABLETYPES_HPP +#include "common/DataTypes.hpp" + namespace geos { diff --git a/src/coreComponents/common/initializeEnvironment.cpp b/src/coreComponents/common/initializeEnvironment.cpp index 86c313e53d1..efbc09d90b3 100644 --- a/src/coreComponents/common/initializeEnvironment.cpp +++ b/src/coreComponents/common/initializeEnvironment.cpp @@ -92,22 +92,16 @@ void setupLogger() { std::string const stackHistory = LvArray::system::stackTrace( true ); - GEOS_LOG( GEOS_FMT( "***** ERROR\n" - "***** LOCATION: (external error, detected {})\n" - "{}\n{}", - detectionLocation, errorMsg, stackHistory ) ); - if( ErrorLogger::global().isOutputFileEnabled() ) - { - ErrorLogger::ErrorMsg error; - error.setType( ErrorLogger::MsgType::Error ); - error.addToMsg( errorMsg ); - error.addRank( ::geos::logger::internal::g_rank ); - error.addCallStackInfo( stackHistory ); - error.addContextInfo( - ErrorContext{ { { ErrorContext::Attribute::DetectionLoc, string( detectionLocation ) } } } ); - - ErrorLogger::global().flushErrorMsg( error ); - } + ErrorLogger::ErrorMsg error; + error.setType( ErrorLogger::MsgType::Error ); + error.addToMsg( errorMsg ); + error.addRank( ::geos::logger::internal::g_rank ); + error.addCallStackInfo( stackHistory ); + error.addContextInfo( + ErrorContext{ { { ErrorContext::Attribute::DetectionLoc, string( detectionLocation ) } }, + string( detectionLocation ) } ); + + ErrorLogger::global().flushErrorMsg( error ); // we do not terminate the program as 1. the error could be non-fatal, 2. there may be more messages to output. } ); @@ -124,26 +118,18 @@ void setupLogger() // error message output std::string const stackHistory = LvArray::system::stackTrace( true ); + ErrorLogger::ErrorMsg error; error.addSignalToMsg( signal ); + error.setType( ErrorLogger::MsgType::Error ); + error.addRank( ::geos::logger::internal::g_rank ); + error.addCallStackInfo( stackHistory ); + error.addContextInfo( + ErrorContext{ { { ErrorContext::Attribute::Signal, std::to_string( signal ) } }, "", 1 }, + ErrorContext{ { { ErrorContext::Attribute::DetectionLoc, string( "signal handler" ) } }, "", 0 } ); - GEOS_LOG( GEOS_FMT( "***** ERROR\n" - "***** SIGNAL: {}\n" - "***** LOCATION: (external error, captured by signal handler)\n" - "{}\n{}", - signal, error.m_msg, stackHistory ) ); + ErrorLogger::global().flushErrorMsg( error ); - if( ErrorLogger::global().isOutputFileEnabled() ) - { - error.setType( ErrorLogger::MsgType::Error ); - error.addRank( ::geos::logger::internal::g_rank ); - error.addCallStackInfo( stackHistory ); - error.addContextInfo( - ErrorContext{ { { ErrorContext::Attribute::Signal, std::to_string( signal ) } }, 1 }, - ErrorContext{ { { ErrorContext::Attribute::DetectionLoc, string( "signal handler" ) } }, 0 } ); - - ErrorLogger::global().flushErrorMsg( error ); - } // call program termination LvArray::system::callErrorHandler(); diff --git a/src/coreComponents/common/logger/ErrorHandling.cpp b/src/coreComponents/common/logger/ErrorHandling.cpp index 5bec5c6754c..9ff3fb9d275 100644 --- a/src/coreComponents/common/logger/ErrorHandling.cpp +++ b/src/coreComponents/common/logger/ErrorHandling.cpp @@ -41,6 +41,61 @@ static constexpr std::string_view g_level3Next = " "; ErrorLogger g_errorLogger{}; +/** + * @brief Retrieve all informations from the ErrorMsg and format and write into a stream. + * @param errMsg Class containing all the error/warning information + * @param oss The output stream to write the content to. + */ +void ErrorLogger::writeToAscii( ErrorLogger::ErrorMsg const & errMsg, std::ostream & oss ) +{ + /// HEADER + oss << "***** " << ErrorLogger::toString( errMsg.m_type ) << "\n"; + if( !errMsg.m_signal.empty()) + { + oss<< "***** SIGNAL: "<< errMsg.m_signal <<"\n"; + } + oss << "***** LOCATION: " << errMsg.m_file<< " l." << errMsg.m_line << "\n"; + oss << "***** " << errMsg.m_cause << "\n"; + oss << "***** Rank " << stringutilities::join( errMsg.m_ranksInfo, ", " ) << "\n"; + + std::vector< ErrorLogger::ErrorContext > const contextsInfo = errMsg.m_contextsInfo; + /// ERROR CONTEXT + if( contextsInfo.empty()) + { + oss << "***** Message :\n"; + oss << errMsg.m_msg << "\n"; + } + else + { + if( contextsInfo.size() >= 1 ) + { + + oss << "***** Message from " << contextsInfo.front().m_dataDisplayString<< ":\n"; + oss << errMsg.m_msg << "\n"; + } + + if( contextsInfo.size() > 1 ) + { + oss << "***** Additional contexts:\n"; + for( size_t i = 1; i< contextsInfo.size(); i++ ) + { + oss << "***** - " << contextsInfo[i].m_dataDisplayString << "\n"; + } + } + + } + ///STACKTRACE + if( errMsg.m_sourceCallStack.size() > 0 ) + { + oss << "\n** StackTrace of "<< errMsg.m_sourceCallStack.size() << " frames **\n"; + for( size_t i = 0; i < errMsg.m_sourceCallStack.size(); i++ ) + { + oss << GEOS_FMT( "Frame {}: {}\n", i, errMsg.m_sourceCallStack[i] ); + } + oss << "=====\n"; + } +} + ErrorLogger & ErrorLogger::global() { return g_errorLogger; } @@ -228,10 +283,10 @@ void ErrorLogger::streamMultilineYamlAttribute( std::string_view msg, std::ofstr } } -void ErrorLogger::flushErrorMsg( ErrorLogger::ErrorMsg & errorMsg ) +void ErrorLogger::writeToYaml( ErrorMsg & errorMsg ) { std::ofstream yamlFile( std::string( m_filename ), std::ios::app ); - if( yamlFile.is_open() && isOutputFileEnabled() ) + if( yamlFile.is_open() ) { // General errors info (type, rank on which the error occured) yamlFile << g_level1Start << "type: " << ErrorLogger::toString( errorMsg.m_type ) << "\n"; @@ -291,12 +346,20 @@ void ErrorLogger::flushErrorMsg( ErrorLogger::ErrorMsg & errorMsg ) yamlFile << "\n"; yamlFile.flush(); errorMsg = ErrorMsg(); - GEOS_LOG_RANK( GEOS_FMT( "The error file {} has been appended.\n", m_filename ) ); + GEOS_LOG_RANK( GEOS_FMT( "The error file {} has been appended.", m_filename ) ); } else { - GEOS_LOG_RANK( GEOS_FMT( "Unable to open error file for writing.\n- Error file: {}\n- Error file enabled = {}.\n", - m_filename, isOutputFileEnabled() ) ); + GEOS_LOG_RANK( GEOS_FMT( "Unable to open error file for writing.\n- Error file: {}\n", m_filename ) ); + } +} + +void ErrorLogger::flushErrorMsg( ErrorMsg & errorMsg ) +{ + writeToAscii( errorMsg, getErrorStream() ); + if( isOutputFileEnabled() ) + { + writeToYaml( errorMsg ); } } diff --git a/src/coreComponents/common/logger/ErrorHandling.hpp b/src/coreComponents/common/logger/ErrorHandling.hpp index 62e3db66df6..b327ddc0525 100644 --- a/src/coreComponents/common/logger/ErrorHandling.hpp +++ b/src/coreComponents/common/logger/ErrorHandling.hpp @@ -21,6 +21,8 @@ #define INITIALIZATION_ERROR_LOGGER_HPP #include "common/DataTypes.hpp" +#include "common/format/Format.hpp" +#include "common/format/StringUtilities.hpp" namespace geos { @@ -33,6 +35,7 @@ class ErrorLogger { public: + /** * @enum MsgType * Enum listing the different types of possible errors @@ -40,6 +43,7 @@ class ErrorLogger enum class MsgType { Error, + ExternalError, Warning, Exception, Undefined @@ -75,6 +79,9 @@ class ErrorLogger /// The key is a field of the Attribute enumeration and is converted to a string for writing in the YAML map< Attribute, std::string > m_attributes; + /// String containing the target object name followed by the the file and line declaring it. + string m_dataDisplayString; + /** * @brief Priority level assigned to an error context. * @details Used to prioritize contextes (higher values = more relevant). Default is 0. @@ -105,6 +112,8 @@ class ErrorLogger { /// the error type (Warning, Error or Exception) MsgType m_type = ErrorLogger::MsgType::Undefined; + /// The signal received and formatted + std::string m_signal; /// the error message that can be completed std::string m_msg; /// the cause of the error (erroneous condition, failed assertion...) if identified (optional) @@ -230,6 +239,13 @@ class ErrorLogger bool m_isValidStackTrace = false; }; + /** + * @brief Format all information in ErrorMsg and write it to the specified output stream + * @param errMsg The struct containing the error/warning object + * @param oss The output stream + */ + static void writeToAscii( ErrorLogger::ErrorMsg const & errMsg, std::ostream & oss ); + /** * @return Global instance of the ErrorLogger class used for error/warning reporting. * @details This global instance is used across the codebase to log errors, warnings, and exceptions, @@ -239,12 +255,6 @@ class ErrorLogger */ GEOS_HOST static ErrorLogger & global(); - /** - * @return true if the YAML file output is enabled - */ - bool isOutputFileEnabled() const - { return m_writeYaml; } - /** * @brief Enable the YAML file output, which is false by default * @param value A value of true enable the file writing @@ -268,9 +278,8 @@ class ErrorLogger /** * @brief Gives acces to the error message that is currently being constructed, - * potencially at various application layers - * Use flushErrorMsg() when the message is fully constructed and you want it to be output - * @return Reference to the current instance for method chaining. + * potencially at various application layers (Typically for exceptions) + * @return Reference to the current error message instance; */ ErrorMsg & currentErrorMsg() { return m_currentErrorMsg; } @@ -293,8 +302,27 @@ class ErrorLogger * and reset the errorMsg instance to its initial state * @param errorMsg a constant reference to the error */ + void writeToYaml( ErrorMsg & errorMsg ); + + /** + * @brief Write all the information retrieved about the error/warning message into the output stream specified and + * optionnaly into a yaml file + * @param errorMsg a constant reference to the ErrorMsg + */ void flushErrorMsg( ErrorMsg & errorMsg ); + /** + * @return Return the const general log stream + */ + std::ostream const & getErrorStream() const + { return m_stream; } + + /** + * @return Return the reference general log stream + */ + std::ostream & getErrorStream() + { return m_stream; } + private: /// The error constructed via exceptions ErrorMsg m_currentErrorMsg; @@ -302,6 +330,15 @@ class ErrorLogger bool m_writeYaml = false; /// YAML file name std::string_view m_filename = "errors.yaml"; + /// The stream used for the log output. By default used std::cout + std::ostream & m_stream = std::cout; + + + /** + * @return true if the YAML file output is enabled + */ + bool isOutputFileEnabled() const + { return m_writeYaml; } /** * @brief Write the error message in the YAML file regarding indentation and line break diff --git a/src/coreComponents/common/logger/GeosExceptions.hpp b/src/coreComponents/common/logger/GeosExceptions.hpp new file mode 100644 index 00000000000..1adf819077d --- /dev/null +++ b/src/coreComponents/common/logger/GeosExceptions.hpp @@ -0,0 +1,250 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file Logger.hpp + */ + + +#include "common/logger/ErrorHandling.hpp" + +namespace geos +{ + +/** + * @brief Geos Exception used in GEOS_THROW + */ +struct Exception : public std::exception +{ +public: + Exception() = default; + + /** + * @brief Constructor + * @param what The error message describing the exception + */ + Exception( std::string const & what ): + std::exception( ) + { + errorMsg.addToMsg( what ); + } + + /** + * @return Reference to the ErrorMsg object + */ + ErrorLogger::ErrorMsg & getErrorMsg() + { return errorMsg; } + + /** + * @brief System fallback to get description content if error system does not achieve to output the ErrorMsg + can also provide exception information to debuggers + * @return Returns The exception message + * @note We does not allow to override what(), it's the GEOS_THROW responsability to write-in the exception message + */ + virtual char const * what() const noexcept override final + { + return m_cachedWhat.c_str(); + } + + /** + * @brief Prepare and cache the formatted exception message + * @param msg The main error message + * @param cause The cause of the exception + * @param file The source file where the exception occurred + * @param line The line number where the exception occurred + * @param rank The MPI rank + * @param stackTrace The stack trace at the point of exception + */ + void prepareWhat( std::string const & msg, + std::string const & cause, + char const * file, + int line, + int rank, + string_view stackTrace ) noexcept + { + try + { + std::ostringstream oss; + oss << "***** GEOS Exception\n"; + oss << "***** LOCATION: " << file << " l." << line << "\n"; + oss << "***** " << cause << "\n"; + oss << "***** Rank " << rank << ": "<< msg <<"\n\n"; + oss << stackTrace; + m_cachedWhat = oss.str(); + } catch( ... ) + { + m_cachedWhat = "GEOS Exception (formatting failed)"; + } + + } + +private: + /// Formatted exception message for what() method + string m_cachedWhat; + /// Error message logger for structured error reporting + ErrorLogger::ErrorMsg errorMsg; +}; + +/** + * @brief Exception class used to report errors in user input. + */ +struct RuntimeError : public geos::Exception +{ + /** + * @brief Constructor + * @param what the error message + */ + RuntimeError( std::string const & what ): + geos::Exception( what ) + {} + + RuntimeError(): geos::Exception(){} +}; + +/** + * @brief Exception class used to report bad GEOS state + */ +struct LogicError : public geos::Exception +{ + /** + * @brief Constructor + * @param what the error message + */ + LogicError( std::string const & what ): + geos::Exception( what ) + {} + + /** + * @brief Default constructor + */ + LogicError(): geos::Exception(){} +}; + +/** + * @brief Exception class used to report errors in user input. + */ +struct DomainError : public geos::Exception +{ + /** + * @brief Constructor + * @param what the error message + */ + DomainError( std::string const & what ): + geos::Exception( what ) + {} + + /** + * @brief Default constructor + */ + DomainError(): geos::Exception(){} +}; +/** + * @brief Exception class used to report errors in user input. + */ +struct InputError : public geos::Exception +{ + /** + * @brief Constructor + * @param what the error message + */ + InputError( std::string const & what ): + geos::Exception( what ) + {} + + /** + * @brief Default constructor + */ + InputError(): geos::Exception(){} + + /** + * @brief Constructor + * @param what the error message + */ + InputError( char const * const what ): + geos::Exception( what ) + {} + + /** + * @brief Constructs an InputError from an underlying exception. + * @param subException The exception on which the created one is based. + * @param msgToInsert The error message that will be inserted in the subException error message. + */ + InputError( std::exception const & subException, std::string const & msgToInsert ); +}; + +/** + * @brief Exception class used to report errors in user input. + */ +struct SimulationError : public geos::Exception +{ + /** + * @brief Constructor + * @param what the error message + */ + SimulationError( std::string const & what ): + geos::Exception( what ) + {} + + /** + * @brief Default constructor + */ + SimulationError(): geos::Exception(){} + + /** + * @brief Constructor + * @param what the error message + */ + SimulationError( char const * const what ): + geos::Exception( what ) + {} + + /** + * @brief Construct a SimulationError from an underlying exception. + * @param subException An exception to base this new one on. + * @param msgToInsert The error message. + * It will be inserted before the error message inside of subException. + */ + SimulationError( std::exception const & subException, std::string const & msgToInsert ); +}; + +/** + * @brief Exception class used to report errors from type conversion + * @todo (ErrorManager EPIC #2940) Consider adding a way to precise custom exception parameters, to add + * expected & encountered typeid for this one (in order to manage the exception output more precisely). + * We could also manage this by having: BadTypeErrorABC <|--- BadTypeError< T > /!\ compilation time + */ +struct BadTypeError : public geos::Exception +{ + /** + * @brief Constructor + * @param what the error message + */ + BadTypeError( std::string const & what ): + geos::Exception( what ) + {} + + /** + * @brief Default constructor + */ + BadTypeError(): geos::Exception(){} +}; + +/** + * @brief Exception class used for special control flow. + */ +class NotAnError : public geos::Exception +{}; + +} diff --git a/src/coreComponents/common/logger/Logger.cpp b/src/coreComponents/common/logger/Logger.cpp index ade2834cbb2..ba1877eb4c9 100644 --- a/src/coreComponents/common/logger/Logger.cpp +++ b/src/coreComponents/common/logger/Logger.cpp @@ -20,7 +20,6 @@ // Source includes #include "Logger.hpp" #include "common/Path.hpp" -#include "common/format/StringUtilities.hpp" namespace geos { @@ -56,11 +55,11 @@ std::string insertExMsg( std::string const & originalMsg, std::string const & ms } InputError::InputError( std::exception const & subException, std::string const & msgToInsert ): - std::runtime_error( insertExMsg( subException.what(), msgToInsert ) ) + geos::Exception( insertExMsg( subException.what(), msgToInsert ) ) {} SimulationError::SimulationError( std::exception const & subException, std::string const & msgToInsert ): - std::runtime_error( insertExMsg( subException.what(), msgToInsert ) ) + geos::Exception( insertExMsg( subException.what(), msgToInsert ) ) {} namespace logger diff --git a/src/coreComponents/common/logger/Logger.hpp b/src/coreComponents/common/logger/Logger.hpp index e59cfa05256..0cd2772fb50 100644 --- a/src/coreComponents/common/logger/Logger.hpp +++ b/src/coreComponents/common/logger/Logger.hpp @@ -20,12 +20,9 @@ #ifndef GEOS_COMMON_LOGGER_HPP #define GEOS_COMMON_LOGGER_HPP -// Source incldes -#include "common/GeosxConfig.hpp" -#include "common/GeosxMacros.hpp" -#include "common/format/Format.hpp" +// Source includes #include "LvArray/src/Macros.hpp" -#include "common/logger/ErrorHandling.hpp" +#include "common/logger/GeosExceptions.hpp" // System includes #include @@ -137,8 +134,8 @@ * @note - Currently not available on GPU. * - Possible to pre-define it in any source file (e.g. for unit tests) */ -#if !defined(GEOS_DEVICE_COMPILE) && !defined(GEOS_ERROR_LOGGER_INSTANCE) -#define GEOS_ERROR_LOGGER_INSTANCE ErrorLogger::global() +#if !defined(GEOS_DEVICE_COMPILE) && !defined(GEOS_GLOBAL_LOGGER) +#define GEOS_GLOBAL_LOGGER ErrorLogger::global() #endif /** @@ -158,34 +155,21 @@ { \ std::ostringstream __msgoss; \ __msgoss << GEOS_DETAIL_FIRST_ARG( __VA_ARGS__ ); \ - std::string __message = __msgoss.str(); \ - __msgoss = std::ostringstream(); \ - __msgoss << CAUSE_MESSAGE; \ - std::string __cause = __msgoss.str(); \ - std::ostringstream __oss; \ - __oss << "***** ERROR\n"; \ - __oss << "***** LOCATION: " LOCATION "\n"; \ - __oss << "***** " << __cause << "\n"; \ - __oss << "***** Rank " << ::geos::logger::internal::g_rankString << ": " << __message << "\n"; \ - std::string stackHistory = LvArray::system::stackTrace( true ); \ - __oss << stackHistory; \ - std::cout << __oss.str() << std::endl; \ - if( GEOS_ERROR_LOGGER_INSTANCE.isOutputFileEnabled() ) \ - { \ - ErrorLogger::ErrorMsg msgStruct( ErrorLogger::MsgType::Error, \ - __message, \ - ::geos::logger::internal::g_rank, \ - __FILE__, \ - __LINE__ ); \ - msgStruct.setCause( __cause ); \ - msgStruct.addCallStackInfo( stackHistory ); \ - msgStruct.addContextInfo( GEOS_DETAIL_REST_ARGS( __VA_ARGS__ ) ); \ - GEOS_ERROR_LOGGER_INSTANCE.flushErrorMsg( msgStruct ); \ - } \ + std::ostringstream __causemsgsoss; \ + __causemsgsoss << CAUSE_MESSAGE; \ + ErrorLogger::ErrorMsg msgStruct( ErrorLogger::MsgType::Error, \ + __msgoss.str(), \ + ::geos::logger::internal::g_rank, \ + __FILE__, \ + __LINE__ ); \ + msgStruct.setCause( __causemsgsoss.str() ); \ + msgStruct.addCallStackInfo( LvArray::system::stackTrace( true ) ); \ + msgStruct.addContextInfo( GEOS_DETAIL_REST_ARGS( __VA_ARGS__ ) ); \ + GEOS_GLOBAL_LOGGER.flushErrorMsg( msgStruct ); \ LvArray::system::callErrorHandler(); \ } \ - } while( false ) -#elif __CUDA_ARCH__ + }while( false ) + #elif __CUDA_ARCH__ #define GEOS_ERROR_IF_CAUSE( COND, CAUSE_MESSAGE, ... ) \ do \ { \ @@ -230,7 +214,7 @@ * - Mandatory first parameter, the type of the exception to throw * - Optional following parameters, context information on the current error (DataContext) */ -#if !defined(GEOS_DEVICE_COMPILE) + #if !defined(GEOS_DEVICE_COMPILE) #define GEOS_THROW_IF_CAUSE( COND, CAUSE_MESSAGE, MSG, ... ) \ do \ { \ @@ -238,36 +222,28 @@ { \ std::ostringstream __msgoss; \ __msgoss << MSG; \ - std::string __message = __msgoss.str(); \ - __msgoss = std::ostringstream(); \ - __msgoss << CAUSE_MESSAGE; \ - std::string __cause = __msgoss.str(); \ - std::ostringstream __oss; \ - __oss << "***** EXCEPTION\n"; \ - __oss << "***** LOCATION: " LOCATION "\n"; \ - __oss << "***** " << __cause << "\n"; \ - __oss << "***** Rank " << ::geos::logger::internal::g_rankString << ": " << __message << "\n"; \ - std::string stackHistory = LvArray::system::stackTrace( true ); \ - __oss << stackHistory; \ - if( GEOS_ERROR_LOGGER_INSTANCE.isOutputFileEnabled() ) \ - { \ - if( GEOS_ERROR_LOGGER_INSTANCE.currentErrorMsg().m_type == ErrorLogger::MsgType::Undefined ) \ - { /* first throw site, we initialize the error message completly */ \ - GEOS_ERROR_LOGGER_INSTANCE.currentErrorMsg() \ - .setType( ErrorLogger::MsgType::Exception ) \ - .setCodeLocation( __FILE__, __LINE__ ) \ - .setCause( __cause ) \ - .addRank( ::geos::logger::internal::g_rank ) \ - .addCallStackInfo( stackHistory ); \ - } \ - GEOS_ERROR_LOGGER_INSTANCE.currentErrorMsg() \ - .addToMsg( __message ) \ - .addContextInfo( GEOS_DETAIL_REST_ARGS( __VA_ARGS__ ) ); \ + std::ostringstream __causemsgsoss; \ + __causemsgsoss << CAUSE_MESSAGE; \ + if( GEOS_GLOBAL_LOGGER.currentErrorMsg().m_type == ErrorLogger::MsgType::Undefined ) \ + { /* first throw site, we initialize the error message completly */ \ + GEOS_GLOBAL_LOGGER.currentErrorMsg() \ + .setType( ErrorLogger::MsgType::Exception ) \ + .setCodeLocation( __FILE__, __LINE__ ) \ + .setCause( __causemsgsoss.str() ) \ + .addRank( ::geos::logger::internal::g_rank ) \ + .addCallStackInfo( LvArray::system::stackTrace( true ) ); \ } \ - throw GEOS_DETAIL_FIRST_ARG( __VA_ARGS__ )( __oss.str() ); \ + GEOS_GLOBAL_LOGGER.currentErrorMsg() \ + .addToMsg( __msgoss.str() ) \ + .addContextInfo( GEOS_DETAIL_REST_ARGS( __VA_ARGS__ ) ); \ + auto ex = GEOS_DETAIL_FIRST_ARG( __VA_ARGS__ )(); \ + ex.prepareWhat( __msgoss.str(), __causemsgsoss.str(), \ + __FILE__, __LINE__, \ + ::geos::logger::internal::g_rank, LvArray::system::stackTrace( true ) ); \ + throw ex; \ } \ - } while( false ) -#elif __CUDA_ARCH__ + }while( false ) + #elif __CUDA_ARCH__ #define GEOS_THROW_IF_CAUSE( COND, CAUSE_MESSAGE, MSG, ... ) \ do \ { \ @@ -321,27 +297,16 @@ { \ std::ostringstream __msgoss; \ __msgoss << GEOS_DETAIL_FIRST_ARG( __VA_ARGS__ ); \ - std::string __message = __msgoss.str(); \ - __msgoss = std::ostringstream(); \ - __msgoss << CAUSE_MESSAGE; \ - std::string __cause = __msgoss.str(); \ - std::ostringstream __oss; \ - __oss << "***** WARNING\n"; \ - __oss << "***** LOCATION: " LOCATION "\n"; \ - __oss << "***** " << __cause << "\n"; \ - __oss << "***** Rank " << ::geos::logger::internal::g_rankString << ": " << __message << "\n"; \ - std::cout << __oss.str() << std::endl; \ - if( GEOS_ERROR_LOGGER_INSTANCE.isOutputFileEnabled() ) \ - { \ - ErrorLogger::ErrorMsg msgStruct( ErrorLogger::MsgType::Warning, \ - __message, \ - ::geos::logger::internal::g_rank, \ - __FILE__, \ - __LINE__ ); \ - msgStruct.setCause( __cause ); \ - msgStruct.addContextInfo( GEOS_DETAIL_REST_ARGS( __VA_ARGS__ ) ); \ - GEOS_ERROR_LOGGER_INSTANCE.flushErrorMsg( msgStruct ); \ - } \ + std::ostringstream __causemsgsoss; \ + __causemsgsoss << CAUSE_MESSAGE; \ + ErrorLogger::ErrorMsg msgStruct( ErrorLogger::MsgType::Warning, \ + __msgoss.str(), \ + ::geos::logger::internal::g_rank, \ + __FILE__, \ + __LINE__ ); \ + msgStruct.setCause( __causemsgsoss.str() ); \ + msgStruct.addContextInfo( GEOS_DETAIL_REST_ARGS( __VA_ARGS__ ) ); \ + GEOS_GLOBAL_LOGGER.flushErrorMsg( msgStruct ); \ } \ } while( false ) #elif __CUDA_ARCH__ @@ -949,88 +914,6 @@ namespace geos { -/** - * @brief Exception class used to report errors in user input. - */ -struct InputError : public std::runtime_error -{ - /** - * @brief Constructor - * @param what the error message - */ - InputError( std::string const & what ): - std::runtime_error( what ) - {} - - /** - * @brief Constructor - * @param what the error message - */ - InputError( char const * const what ): - std::runtime_error( what ) - {} - - /** - * @brief Constructs an InputError from an underlying exception. - * @param subException The exception on which the created one is based. - * @param msgToInsert The error message that will be inserted in the subException error message. - */ - InputError( std::exception const & subException, std::string const & msgToInsert ); -}; - -/** - * @brief Exception class used to report errors in user input. - */ -struct SimulationError : public std::runtime_error -{ - /** - * @brief Constructor - * @param what the error message - */ - SimulationError( std::string const & what ): - std::runtime_error( what ) - {} - - /** - * @brief Constructor - * @param what the error message - */ - SimulationError( char const * const what ): - std::runtime_error( what ) - {} - - /** - * @brief Construct a SimulationError from an underlying exception. - * @param subException An exception to base this new one on. - * @param msgToInsert The error message. - * It will be inserted before the error message inside of subException. - */ - SimulationError( std::exception const & subException, std::string const & msgToInsert ); -}; - -/** - * @brief Exception class used to report errors from type conversion - * @todo (ErrorManager EPIC #2940) Consider adding a way to precise custom exception parameters, to add - * expected & encountered typeid for this one (in order to manage the exception output more precisely). - * We could also manage this by having: BadTypeErrorABC <|--- BadTypeError< T > /!\ compilation time - */ -struct BadTypeError : public std::runtime_error -{ - /** - * @brief Constructor - * @param what the error message - */ - BadTypeError( std::string const & what ): - std::runtime_error( what ) - {} -}; - -/** - * @brief Exception class used for special control flow. - */ -class NotAnError : public std::exception -{}; - namespace logger { diff --git a/src/coreComponents/common/unitTests/testDataTypes.cpp b/src/coreComponents/common/unitTests/testDataTypes.cpp index 5c2daf1655a..58ebc681cae 100644 --- a/src/coreComponents/common/unitTests/testDataTypes.cpp +++ b/src/coreComponents/common/unitTests/testDataTypes.cpp @@ -58,8 +58,6 @@ TEST( testDataTypes, testBoundChecking ) } }, std::out_of_range ); - // std::cout <<" sdsfs "<< mapBoundsChecking.get_inserted(0)<< std::endl; - // std::cout << mapBoundsChecking.get_inserted(1); internal::StdMapWrapper< std::unordered_map< integer, integer >, true > unorderedMapBoundsChecking{{0, 1}}; EXPECT_THROW( { diff --git a/src/coreComponents/common/unitTests/testUnits.cpp b/src/coreComponents/common/unitTests/testUnits.cpp index 9dc1685632d..2fdd6823f83 100644 --- a/src/coreComponents/common/unitTests/testUnits.cpp +++ b/src/coreComponents/common/unitTests/testUnits.cpp @@ -155,3 +155,11 @@ TEST( Units, SystemDurationFormatTest ) } } } + + +int main( int ac, char * av[] ) +{ + ::testing::InitGoogleTest( &ac, av ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/src/coreComponents/constitutiveDrivers/fluid/multiFluid/PVTDriver.cpp b/src/coreComponents/constitutiveDrivers/fluid/multiFluid/PVTDriver.cpp index db232e5c37d..d6469615055 100644 --- a/src/coreComponents/constitutiveDrivers/fluid/multiFluid/PVTDriver.cpp +++ b/src/coreComponents/constitutiveDrivers/fluid/multiFluid/PVTDriver.cpp @@ -207,7 +207,7 @@ bool PVTDriver::execute( real64 const GEOS_UNUSED_PARAM( time_n ), { // this code only makes sense in serial - GEOS_THROW_IF( MpiWrapper::commRank() > 0, "PVTDriver should only be run in serial", std::runtime_error ); + GEOS_THROW_IF( MpiWrapper::commRank() > 0, "PVTDriver should only be run in serial", geos::RuntimeError ); // get the fluid out of the constitutive manager. // for the moment it is of type MultiFluidBase. @@ -372,21 +372,21 @@ void PVTDriver::compareWithBaseline() { for( integer col=0; col < m_table.size( 1 ); ++col ) { - GEOS_THROW_IF( file.eof(), "Baseline file appears shorter than internal results", std::runtime_error ); + GEOS_THROW_IF( file.eof(), "Baseline file appears shorter than internal results", geos::RuntimeError ); file >> value; real64 const error = fabs( m_table[row][col]-value ) / ( fabs( value )+1 ); GEOS_THROW_IF( error > MultiFluidConstants::baselineTolerance, GEOS_FMT( "Results do not match baseline ({} vs {}) at data row {} (row {} with header) and column {}", m_table[row][col], value, row+1, row+headerRows, col+1 ), - std::runtime_error ); + geos::RuntimeError ); } } // check we actually reached the end of the baseline file file >> value; - GEOS_THROW_IF( !file.eof(), "Baseline file appears longer than internal results", std::runtime_error ); + GEOS_THROW_IF( !file.eof(), "Baseline file appears longer than internal results", geos::RuntimeError ); // success diff --git a/src/coreComponents/constitutiveDrivers/fluid/multiFluid/reactive/ReactiveFluidDriver.cpp b/src/coreComponents/constitutiveDrivers/fluid/multiFluid/reactive/ReactiveFluidDriver.cpp index 8bf8db3077d..24afcd65d15 100644 --- a/src/coreComponents/constitutiveDrivers/fluid/multiFluid/reactive/ReactiveFluidDriver.cpp +++ b/src/coreComponents/constitutiveDrivers/fluid/multiFluid/reactive/ReactiveFluidDriver.cpp @@ -127,7 +127,7 @@ bool ReactiveFluidDriver::execute( real64 const GEOS_UNUSED_PARAM( time_n ), { // this code only makes sense in serial - GEOS_THROW_IF( MpiWrapper::commRank() > 0, "ReactiveFluidDriver should only be run in serial", std::runtime_error ); + GEOS_THROW_IF( MpiWrapper::commRank() > 0, "ReactiveFluidDriver should only be run in serial", geos::RuntimeError ); // get the fluid out of the constitutive manager. // for the moment it is of type MultiFluidBase. @@ -324,20 +324,20 @@ void ReactiveFluidDriver::compareWithBaseline() { for( integer col=0; col < m_table.size( 1 ); ++col ) { - GEOS_THROW_IF( file.eof(), "Baseline file appears shorter than internal results", std::runtime_error ); + GEOS_THROW_IF( file.eof(), "Baseline file appears shorter than internal results", geos::RuntimeError ); file >> value; error = fabs( m_table[row][col]-value ) / ( fabs( value )+1 ); GEOS_THROW_IF( error > m_baselineTol, "Results do not match baseline at data row " << row+1 << " (row " << row+m_numColumns << " with header)" - << " and column " << col+1, std::runtime_error ); + << " and column " << col+1, geos::RuntimeError ); } } // check we actually reached the end of the baseline file file >> value; - GEOS_THROW_IF( !file.eof(), "Baseline file appears longer than internal results", std::runtime_error ); + GEOS_THROW_IF( !file.eof(), "Baseline file appears longer than internal results", geos::RuntimeError ); // success diff --git a/src/coreComponents/constitutiveDrivers/relativePermeability/RelpermDriver.cpp b/src/coreComponents/constitutiveDrivers/relativePermeability/RelpermDriver.cpp index 49dca10b482..a46e6927baa 100644 --- a/src/coreComponents/constitutiveDrivers/relativePermeability/RelpermDriver.cpp +++ b/src/coreComponents/constitutiveDrivers/relativePermeability/RelpermDriver.cpp @@ -110,7 +110,7 @@ bool RelpermDriver::execute( const geos::real64 GEOS_UNUSED_PARAM( time_n ), { // this code only makes sense in serial - GEOS_THROW_IF( MpiWrapper::commRank() > 0, "RelpermDriver should only be run in serial", std::runtime_error ); + GEOS_THROW_IF( MpiWrapper::commRank() > 0, "RelpermDriver should only be run in serial", geos::RuntimeError ); ConstitutiveManager @@ -301,7 +301,7 @@ void RelpermDriver::compareWithBaseline() { for( integer col = 0; col < m_table.size( 1 ); ++col ) { - GEOS_THROW_IF( file.eof(), "Baseline file appears shorter than internal results", std::runtime_error ); + GEOS_THROW_IF( file.eof(), "Baseline file appears shorter than internal results", geos::RuntimeError ); file >> value; real64 const error = fabs( m_table[row][col] - value ) / ( fabs( value ) + 1 ); @@ -310,14 +310,14 @@ void RelpermDriver::compareWithBaseline() << row + m_numColumns << " with header)" << " and column " << col + 1, - std::runtime_error ); + geos::RuntimeError ); } } // check we actually reached the end of the baseline file file >> value; - GEOS_THROW_IF( !file.eof(), "Baseline file appears longer than internal results", std::runtime_error ); + GEOS_THROW_IF( !file.eof(), "Baseline file appears longer than internal results", geos::RuntimeError ); // success diff --git a/src/coreComponents/constitutiveDrivers/solid/TriaxialDriver.cpp b/src/coreComponents/constitutiveDrivers/solid/TriaxialDriver.cpp index 73bea40106f..0dd8ad22c75 100644 --- a/src/coreComponents/constitutiveDrivers/solid/TriaxialDriver.cpp +++ b/src/coreComponents/constitutiveDrivers/solid/TriaxialDriver.cpp @@ -394,7 +394,7 @@ bool TriaxialDriver::execute( real64 const GEOS_UNUSED_PARAM( time_n ), { // this code only makes sense in serial - GEOS_THROW_IF( MpiWrapper::commRank() > 0, "Triaxial Driver should only be run in serial", std::runtime_error ); + GEOS_THROW_IF( MpiWrapper::commRank() > 0, "Triaxial Driver should only be run in serial", geos::RuntimeError ); // get the solid out of the constitutive manager. // for the moment it is of type SolidBase. @@ -560,7 +560,7 @@ void TriaxialDriver::compareWithBaseline() { for( integer col=0; col < m_table.size( 1 ); ++col ) { - GEOS_THROW_IF( file.eof(), "Baseline file appears shorter than internal results", std::runtime_error ); + GEOS_THROW_IF( file.eof(), "Baseline file appears shorter than internal results", geos::RuntimeError ); file >> value; if( col < ITER ) // only compare "real" data columns @@ -568,7 +568,7 @@ void TriaxialDriver::compareWithBaseline() error = fabs( m_table[row][col]-value ) / ( fabs( value )+1 ); GEOS_THROW_IF( error > m_baselineTol, "Results do not match baseline at data row " << row+1 << " (row " << row+10 << " with header)" - << " and column " << col+1, std::runtime_error ); + << " and column " << col+1, geos::RuntimeError ); } } } @@ -576,7 +576,7 @@ void TriaxialDriver::compareWithBaseline() // check we actually reached the end of the baseline file file >> value; - GEOS_THROW_IF( !file.eof(), "Baseline file appears longer than internal results", std::runtime_error ); + GEOS_THROW_IF( !file.eof(), "Baseline file appears longer than internal results", geos::RuntimeError ); // success diff --git a/src/coreComponents/dataRepository/DataContext.cpp b/src/coreComponents/dataRepository/DataContext.cpp index 8e01140759f..4dcb820c716 100644 --- a/src/coreComponents/dataRepository/DataContext.cpp +++ b/src/coreComponents/dataRepository/DataContext.cpp @@ -112,7 +112,8 @@ ErrorLogger::ErrorContext DataFileContext::getContextInfo() const { ErrorLogger::ErrorContext ctxInfo{ { { ErrorLogger::ErrorContext::Attribute::InputFile, m_filePath }, - { ErrorLogger::ErrorContext::Attribute::InputLine, std::to_string( m_line )} } // m_attributes + { ErrorLogger::ErrorContext::Attribute::InputLine, std::to_string( m_line )} }, + toString() }; return ctxInfo; } diff --git a/src/coreComponents/dataRepository/Group.cpp b/src/coreComponents/dataRepository/Group.cpp index 409fff42c61..b9ece9eb301 100644 --- a/src/coreComponents/dataRepository/Group.cpp +++ b/src/coreComponents/dataRepository/Group.cpp @@ -695,7 +695,7 @@ Group const & Group::getBaseGroupByPath( string const & path ) const GEOS_THROW_IF( !foundTarget, "Could not find the specified path start.\n"<< "Specified path is " << path, - std::domain_error ); + geos::DomainError ); } string::size_type currentPosition; diff --git a/src/coreComponents/dataRepository/Group.hpp b/src/coreComponents/dataRepository/Group.hpp index bf185a656ef..86ff2215e42 100644 --- a/src/coreComponents/dataRepository/Group.hpp +++ b/src/coreComponents/dataRepository/Group.hpp @@ -312,7 +312,7 @@ class Group * @tparam KEY The type of the lookup. * @param key The key used to perform the lookup. * @return A reference to @p T that refers to the sub-group. - * @throw std::domain_error If the Group does not exist is thrown. + * @throw geos::DomainError If the Group does not exist is thrown. */ template< typename T = Group, typename KEY = void > T & getGroup( KEY const & key ) @@ -321,7 +321,7 @@ class Group GEOS_THROW_IF( child == nullptr, "Group " << getDataContext() << " has no child named " << key << std::endl << dumpSubGroupsNames(), - std::domain_error, getDataContext() ); + geos::DomainError, getDataContext() ); T * const castedChild = dynamicCast< T * >( child ); GEOS_THROW_IF( castedChild == nullptr, GEOS_FMT( "{} was expected to be a '{}'.", @@ -340,7 +340,7 @@ class Group GEOS_THROW_IF( child == nullptr, "Group " << getDataContext() << " has no child named " << key << std::endl << dumpSubGroupsNames(), - std::domain_error, getDataContext() ); + geos::DomainError, getDataContext() ); T const * const castedChild = dynamicCast< T const * >( child ); GEOS_THROW_IF( castedChild == nullptr, GEOS_FMT( "{} was expected to be a '{}'.", @@ -356,7 +356,7 @@ class Group * to lookup the Group to return. Absolute paths search * from the tree root, while relative - from current group. * @return A reference to @p T that refers to the sub-group. - * @throw std::domain_error If the Group doesn't exist. + * @throw geos::DomainError If the Group doesn't exist. */ template< typename T = Group > T & getGroupByPath( string const & path ) @@ -1117,7 +1117,7 @@ class Group * @tparam KEY The lookup type. * @param key The value used to lookup the wrapper. * @return A reference to the WrapperBase that resulted from the lookup. - * @throw std::domain_error if the wrapper doesn't exist. + * @throw geos::DomainError if the wrapper doesn't exist. */ template< typename KEY > WrapperBase const & getWrapperBase( KEY const & key ) const @@ -1126,7 +1126,7 @@ class Group GEOS_THROW_IF( wrapper == nullptr, "Group " << getDataContext() << " has no wrapper named " << key << std::endl << dumpWrappersNames(), - std::domain_error, getDataContext() ); + geos::DomainError, getDataContext() ); return *wrapper; } @@ -1141,7 +1141,7 @@ class Group GEOS_THROW_IF( wrapper == nullptr, "Group " << getDataContext() << " has no wrapper named " << key << std::endl << dumpWrappersNames(), - std::domain_error, getDataContext() ); + geos::DomainError, getDataContext() ); return *wrapper; } @@ -1210,7 +1210,7 @@ class Group * @tparam LOOKUP_TYPE the type of key used to perform the lookup * @param[in] index a lookup value used to search the collection of wrappers * @return A reference to the Wrapper that resulted from the lookup. - * @throw std::domain_error if the Wrapper doesn't exist. + * @throw geos::DomainError if the Wrapper doesn't exist. */ template< typename T, typename LOOKUP_TYPE > Wrapper< T > const & getWrapper( LOOKUP_TYPE const & index ) const @@ -1268,7 +1268,7 @@ class Group * @tparam LOOKUP_TYPE type of value used for wrapper lookup * @param lookup value for wrapper lookup * @return reference to @p T - * @throw A std::domain_error if the Wrapper does not exist. + * @throw A geos::DomainError if the Wrapper does not exist. */ template< typename T, typename LOOKUP_TYPE > GEOS_DECLTYPE_AUTO_RETURN @@ -1350,7 +1350,7 @@ class Group * this group that can be used in output messages. * @tparam KEY The lookup type. * @param key The value used to lookup the wrapper. - * @throw std::domain_error if the wrapper doesn't exist. + * @throw geos::DomainError if the wrapper doesn't exist. */ template< typename KEY > DataContext const & getWrapperDataContext( KEY key ) const @@ -1359,13 +1359,13 @@ class Group /** * @brief Access the group's parent. * @return reference to parent Group - * @throw std::domain_error if the Group doesn't have a parent. + * @throw geos::DomainError if the Group doesn't have a parent. */ Group & getParent() { GEOS_THROW_IF( m_parent == nullptr, "Group at " << getDataContext() << " does not have a parent.", - std::domain_error, getDataContext() ); + geos::DomainError, getDataContext() ); return *m_parent; } @@ -1376,7 +1376,7 @@ class Group { GEOS_THROW_IF( m_parent == nullptr, "Group at " << getDataContext() << " does not have a parent.", - std::domain_error, getDataContext() ); + geos::DomainError, getDataContext() ); return *m_parent; } diff --git a/src/coreComponents/dataRepository/GroupContext.cpp b/src/coreComponents/dataRepository/GroupContext.cpp index f5085f51663..ec37336f2ab 100644 --- a/src/coreComponents/dataRepository/GroupContext.cpp +++ b/src/coreComponents/dataRepository/GroupContext.cpp @@ -57,7 +57,8 @@ string GroupContext::toString() const ErrorLogger::ErrorContext GroupContext::getContextInfo() const { ErrorLogger::ErrorContext ctxInfo{ - { { ErrorLogger::ErrorContext::Attribute::DataPath, toString() } } // m_attributes + { { ErrorLogger::ErrorContext::Attribute::DataPath, GEOS_FMT( "{}/{}", m_group.getPath(), m_targetName )} }, + toString() }; return ctxInfo; } diff --git a/src/coreComponents/dataRepository/WrapperContext.cpp b/src/coreComponents/dataRepository/WrapperContext.cpp index 50a37277e32..d2a5194020f 100644 --- a/src/coreComponents/dataRepository/WrapperContext.cpp +++ b/src/coreComponents/dataRepository/WrapperContext.cpp @@ -41,7 +41,8 @@ string WrapperContext::toString() const ErrorLogger::ErrorContext WrapperContext::getContextInfo() const { ErrorLogger::ErrorContext ctxInfo{ - { { ErrorLogger::ErrorContext::Attribute::DataPath, toString() } } // m_attributes + { { ErrorLogger::ErrorContext::Attribute::DataPath, GEOS_FMT( "{}/{}", m_group.getPath(), m_typeName ) } }, + toString() }; return ctxInfo; } diff --git a/src/coreComponents/dataRepository/python/PyGroup.cpp b/src/coreComponents/dataRepository/python/PyGroup.cpp index 9fa25b2db3c..db16370b826 100644 --- a/src/coreComponents/dataRepository/python/PyGroup.cpp +++ b/src/coreComponents/dataRepository/python/PyGroup.cpp @@ -194,8 +194,8 @@ static PyObject * PyGroup_getGroup( PyGroup * const self, PyObject * const args { return createNewPyGroup( self->group->getGroupByPath( path ) ); } - // If the path isn't valid then getGroupByPath will throw a std::domain_error - catch( std::domain_error const & e ) + // If the path isn't valid then getGroupByPath will throw a geos::DomainError + catch( geos::DomainError const & e ) { // If no default return value was specified then this results in a Python exception. if( defaultReturnValue == nullptr ) @@ -259,8 +259,8 @@ static PyObject * PyGroup_getWrapper( PyGroup * const self, PyObject * const arg dataRepository::WrapperBase & wrapper = group.getWrapperBase( wrapperName ); return createNewPyWrapper( wrapper ); } - // If the path isn't valid then either getGroupByPath or getWrapperBase will throw a std::domain_error - catch( std::domain_error const & e ) + // If the path isn't valid then either getGroupByPath or getWrapperBase will throw a geos::DomainError + catch( geos::DomainError const & e ) { // If no default return value was specified then this results in a Python exception. if( defaultReturnValue == nullptr ) diff --git a/src/coreComponents/dataRepository/unitTests/testErrorHandling.cpp b/src/coreComponents/dataRepository/unitTests/testErrorHandling.cpp index 39103cc5580..3541b851475 100644 --- a/src/coreComponents/dataRepository/unitTests/testErrorHandling.cpp +++ b/src/coreComponents/dataRepository/unitTests/testErrorHandling.cpp @@ -30,8 +30,8 @@ using namespace dataRepository; namespace fs = std::filesystem; // redeging logger instance to test macros with a local instance (to prevent any side effect) -#undef GEOS_ERROR_LOGGER_INSTANCE -#define GEOS_ERROR_LOGGER_INSTANCE testErrorLogger +#undef GEOS_GLOBAL_LOGGER +#define GEOS_GLOBAL_LOGGER testErrorLogger // declare a constant which value is the source file line (to predict the error file output). #define GET_LINE( lineVar ) static size_t constexpr lineVar = __LINE__ @@ -173,15 +173,26 @@ TEST( ErrorHandling, testYamlFileExceptionOutput ) // Stacked exception test (contexts must appear sorted by priority) try { - line1 = __LINE__; GEOS_THROW_IF( testValue == 5, "Empty Group: " << context.toString(), std::domain_error, context ); + line1 = __LINE__; GEOS_THROW_IF( testValue == 5, "Empty Group", geos::DomainError, context ); } - catch( std::domain_error const & ex ) + catch( geos::DomainError const & ex ) { string const errorMsg = "Table input error.\n"; testErrorLogger.currentErrorMsg() .addToMsg( errorMsg ) .addContextInfo( additionalContext.getContextInfo() ) .addContextInfo( importantAdditionalContext.getContextInfo().setPriority( 2 ) ); + + string const whatExpected = GEOS_FMT( "***** GEOS Exception\n" + "***** LOCATION: {} l.{}\n" + "***** Error cause: testValue == 5\n" + "***** Rank 0: Empty Group", + testErrorLogger.currentErrorMsg().m_file, line1 ); + + GEOS_ERROR_IF_EQ_MSG( string( ex.what() ).find( whatExpected ), string::npos, + "The error message was not containing the expected sequence.\n" << + " Error message :\n" << ex.what() << + " expected sequence :\n" << whatExpected ); } testErrorLogger.flushErrorMsg( testErrorLogger.currentErrorMsg() ); @@ -193,7 +204,7 @@ TEST( ErrorHandling, testYamlFileExceptionOutput ) rank: 0 message: >- Table input error. - Empty Group: Base Test Class (file.xml, l.23) + Empty Group contexts: - priority: 2 inputFile: /path/to/file.xml @@ -264,6 +275,52 @@ TEST( ErrorHandling, testYamlFileErrorOutput ) } ); } + +TEST( ErrorHandling, testLogFileExceptionOutput ) +{ + ErrorLogger testErrorLogger; + + size_t line1; + + try + { + line1 = __LINE__; GEOS_THROW_IF( testValue == 5, "Empty Group", geos::DomainError, context ); + } + catch( geos::DomainError const & ex ) + { + string const errorMsg = "Table input error.\n"; + ErrorLogger::ErrorMsg currErrorMsg = testErrorLogger.currentErrorMsg(); + currErrorMsg + .addToMsg( errorMsg ) + .addContextInfo( additionalContext.getContextInfo() ) + .addContextInfo( importantAdditionalContext.getContextInfo().setPriority( 2 ) ); + + string const streamExpected = GEOS_FMT( + "***** Exception\n" + "***** LOCATION: {} l.{}\n" + "***** {}\n" + "***** Rank 0\n" + "***** Message from {}:\n" + "{}\n" + "***** Additional contexts:\n" + "***** - {}\n" + "***** - {}\n", + currErrorMsg.m_file, line1, + currErrorMsg.m_cause, + context.toString(), + currErrorMsg.m_msg, + additionalContext.toString(), + importantAdditionalContext.toString(), currErrorMsg.m_sourceCallStack ); + std::ostringstream oss; + ErrorLogger::writeToAscii( currErrorMsg, oss ); + GEOS_ERROR_IF_EQ_MSG( oss.str().find( streamExpected ), string::npos, + "The error message was not containing the expected sequence.\n" << + "The error message was not containing the expected sequence.\n" << + " Error message :\n" <( targetTokens[1] ) ) @@ -179,7 +179,7 @@ dataRepository::Group const * HistoryCollectionBase::getTargetObject( DomainPart GEOS_THROW_IF( targetTokens.size() <= 4, GEOS_FMT( " Object Path '{}' does not target any element sub region", objectPath ), - std::runtime_error ); + geos::RuntimeError ); ElementRegionManager const & elemRegionManager = meshLevel.getElemManager(); string const elemRegionName = targetTokens[3]; ElementRegionBase const & elemRegion = elemRegionManager.getRegion( elemRegionName ); @@ -200,7 +200,7 @@ dataRepository::Group const * HistoryCollectionBase::getTargetObject( DomainPart { GEOS_THROW( targetTokens[pathLevel] << " not found in path " << objectPath << std::endl << targetGroup->dumpSubGroupsNames(), - std::domain_error ); + geos::DomainError ); } } } diff --git a/src/coreComponents/functions/TableFunction.cpp b/src/coreComponents/functions/TableFunction.cpp index 7ee6c4a3490..4446d2be72b 100644 --- a/src/coreComponents/functions/TableFunction.cpp +++ b/src/coreComponents/functions/TableFunction.cpp @@ -81,7 +81,7 @@ void TableFunction::readFile( string const & filename, array1d< real64 > & targe { parseFile( filename, target, skipped ); } - catch( std::runtime_error const & e ) + catch( geos::RuntimeError const & e ) { GEOS_THROW( GEOS_FMT( "{} {}: {}", catalogName(), getDataContext(), e.what() ), InputError ); } diff --git a/src/coreComponents/integrationTests/dataRepositoryTests/testGroupPath.cpp b/src/coreComponents/integrationTests/dataRepositoryTests/testGroupPath.cpp index 3927a3812b4..8174481d720 100644 --- a/src/coreComponents/integrationTests/dataRepositoryTests/testGroupPath.cpp +++ b/src/coreComponents/integrationTests/dataRepositoryTests/testGroupPath.cpp @@ -14,6 +14,7 @@ */ // Source includes +#include "common/logger/ErrorHandling.hpp" #include "mainInterface/ProblemManager.hpp" #include "mainInterface/initialization.hpp" #include "mainInterface/GeosxState.hpp" @@ -104,13 +105,17 @@ TEST( testGroupPath, testGlobalPaths ) { problem.getGroupByPath( "/Mesh/mesh2" ); } - catch( const std::domain_error & e ) + catch( geos::Exception & e ) { static constexpr auto expectedMsg = "***** Error cause: child == nullptr\n" - "***** Rank 0: Group Mesh (CodeIncludedXML0, l.10) has no child named mesh2\n" + "***** Rank 0\n" + "***** Message from Mesh (CodeIncludedXML0, l.10):\n" + "Group Mesh (CodeIncludedXML0, l.10) has no child named mesh2\n" "The children of Mesh are: { mesh1 }"; // checks if the exception contains the expected message - GEOS_ERROR_IF_EQ_MSG( string( e.what() ).find( expectedMsg ), string::npos, + std::ostringstream stream; + geos::ErrorLogger::writeToAscii( ErrorLogger::global().currentErrorMsg(), stream ); + GEOS_ERROR_IF_EQ_MSG( string( stream.str() ).find( expectedMsg ), string::npos, "The error message was not containing the expected sequence.\n" << " Error message :\n" << e.what() << " expected sequence :\n" << expectedMsg ); diff --git a/src/coreComponents/linearAlgebra/multiscale/mesh/coarsening/MetisInterface.cpp b/src/coreComponents/linearAlgebra/multiscale/mesh/coarsening/MetisInterface.cpp index 7fdfcb333b4..df30b457b45 100644 --- a/src/coreComponents/linearAlgebra/multiscale/mesh/coarsening/MetisInterface.cpp +++ b/src/coreComponents/linearAlgebra/multiscale/mesh/coarsening/MetisInterface.cpp @@ -87,7 +87,7 @@ void partition( CRSMatrixView< int64_t const, int64_t const, int64_t const > con options, // options &objval, // edgecut partition.data() ); // part - GEOS_THROW_IF_NE_MSG( result, METIS_OK, "METIS call failed", std::runtime_error ); + GEOS_THROW_IF_NE_MSG( result, METIS_OK, "METIS call failed", geos::RuntimeError ); } } // namespace metis diff --git a/src/coreComponents/linearAlgebra/multiscale/mesh/coarsening/PartitionerBase.cpp b/src/coreComponents/linearAlgebra/multiscale/mesh/coarsening/PartitionerBase.cpp index ea0d251b4c7..14a1d37d325 100644 --- a/src/coreComponents/linearAlgebra/multiscale/mesh/coarsening/PartitionerBase.cpp +++ b/src/coreComponents/linearAlgebra/multiscale/mesh/coarsening/PartitionerBase.cpp @@ -38,7 +38,7 @@ PartitionerBase::create( LinearSolverParameters::Multiscale::Coarsening params ) case PartitionType::semistructured: return std::make_unique< SemistructuredPartitioner >( std::move( params ) ); default: { - GEOS_THROW( "Multiscale partitioning not supported yet: " << params.partitionType, std::runtime_error ); + GEOS_THROW( "Multiscale partitioning not supported yet: " << params.partitionType, geos::RuntimeError ); } } } diff --git a/src/coreComponents/mainInterface/GeosxState.cpp b/src/coreComponents/mainInterface/GeosxState.cpp index 5929b2c99d3..42ec604d228 100644 --- a/src/coreComponents/mainInterface/GeosxState.cpp +++ b/src/coreComponents/mainInterface/GeosxState.cpp @@ -126,7 +126,7 @@ bool GeosxState::initializeDataRepository() GEOS_MARK_FUNCTION; Timer timer( m_initTime ); - GEOS_THROW_IF_NE( m_state, State::UNINITIALIZED, std::logic_error ); + GEOS_THROW_IF_NE( m_state, State::UNINITIALIZED, geos::LogicError ); getProblemManager().parseCommandLineInput(); @@ -156,7 +156,7 @@ void GeosxState::applyInitialConditions() GEOS_MARK_FUNCTION; Timer timer( m_initTime ); - GEOS_THROW_IF_NE( m_state, State::INITIALIZED, std::logic_error ); + GEOS_THROW_IF_NE( m_state, State::INITIALIZED, geos::LogicError ); getProblemManager().applyInitialConditions(); @@ -175,7 +175,7 @@ void GeosxState::run() GEOS_MARK_FUNCTION; Timer timer( m_runTime ); - GEOS_THROW_IF_NE( m_state, State::READY_TO_RUN, std::logic_error ); + GEOS_THROW_IF_NE( m_state, State::READY_TO_RUN, geos::LogicError ); if( getCommandLineOptions().onlyValidateInput ) { diff --git a/src/coreComponents/mesh/FaceManager.cpp b/src/coreComponents/mesh/FaceManager.cpp index 1cf388d34f4..04571d66e8d 100644 --- a/src/coreComponents/mesh/FaceManager.cpp +++ b/src/coreComponents/mesh/FaceManager.cpp @@ -314,7 +314,7 @@ void FaceManager::sortFaceNodes( arrayView2d< real64 const, nodes::REFERENCE_POS GEOS_THROW_IF_GT_MSG( numFaceNodes, MAX_FACE_NODES, GEOS_FMT( "The number of maximum nodes allocated per cell face has been reached " "at position {}.", elementCenter ), - std::runtime_error ); + geos::RuntimeError ); localIndex const firstNodeIndex = faceNodes[0]; diff --git a/src/coreComponents/mesh/generators/VTKUtilities.cpp b/src/coreComponents/mesh/generators/VTKUtilities.cpp index 1f21a300d52..bdda87aff30 100644 --- a/src/coreComponents/mesh/generators/VTKUtilities.cpp +++ b/src/coreComponents/mesh/generators/VTKUtilities.cpp @@ -1170,7 +1170,7 @@ ensureNoEmptyRank( vtkSmartPointer< vtkDataSet > mesh, localIndex const lastRecipientPosition = firstRecipientPosition + numElems - 1; GEOS_THROW_IF( isLastDonor && ( lastRecipientPosition < recipientRanks.size() ), "The current implementation is unable to guarantee that all ranks have at least one element", - std::runtime_error ); + geos::RuntimeError ); for( localIndex iElem = 1; iElem < numElems; ++iElem ) // I only keep my first element { diff --git a/src/coreComponents/physicsSolvers/PhysicsSolverBase.cpp b/src/coreComponents/physicsSolvers/PhysicsSolverBase.cpp index 8d301476cc5..2c40697121a 100644 --- a/src/coreComponents/physicsSolvers/PhysicsSolverBase.cpp +++ b/src/coreComponents/physicsSolvers/PhysicsSolverBase.cpp @@ -1174,7 +1174,7 @@ real64 PhysicsSolverBase::explicitStep( real64 const & GEOS_UNUSED_PARAM( time_n integer const GEOS_UNUSED_PARAM( cycleNumber ), DomainPartition & GEOS_UNUSED_PARAM( domain ) ) { - GEOS_THROW( "PhysicsSolverBase::ExplicitStep called!. Should be overridden.", std::runtime_error ); + GEOS_THROW( "PhysicsSolverBase::ExplicitStep called!. Should be overridden.", geos::RuntimeError ); return 0; } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseBase.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseBase.cpp index 290fbed04ab..37403ceca63 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseBase.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseBase.cpp @@ -1275,7 +1275,7 @@ void CompositionalMultiphaseBase::computeHydrostaticEquilibrium( DomainPartition ": hydrostatic pressure initialization failed to converge in region " << region.getName() << "! \n" << "Try to loosen the equilibration tolerance, or increase the number of equilibration iterations. \n" << "If nothing works, something may be wrong in the fluid model, see ", - std::runtime_error, getDataContext() ); + geos::RuntimeError, getDataContext() ); GEOS_LOG_RANK_0_IF( returnValue == isothermalCompositionalMultiphaseBaseKernels::HydrostaticPressureKernel::ReturnType::DETECTED_MULTIPHASE_FLOW, getCatalogName() << " " << getDataContext() << diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseHybridFVM.cpp b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseHybridFVM.cpp index 7f1998b66a1..2a624108899 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseHybridFVM.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/CompositionalMultiphaseHybridFVM.cpp @@ -182,7 +182,7 @@ void CompositionalMultiphaseHybridFVM::initializePostInitialConditionsPreSubGrou GEOS_THROW_IF( minVal.get() <= 0.0, getCatalogName() << " " << getDataContext() << ": the transmissibility multipliers used in SinglePhaseHybridFVM must be strictly larger than 0.0", - std::runtime_error ); + geos::RuntimeError ); // Initialize face-based constitutive property arrays to zero to prevent uninitialized memory usage on GPU arrayView2d< real64, compflow::USD_PHASE > facePhaseMob = faceManager.getField< flow::facePhaseMobility >(); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp index 6fca54281ae..5dc05b9fc56 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp @@ -579,7 +579,7 @@ void SinglePhaseBase::computeHydrostaticEquilibrium( DomainPartition & domain ) GEOS_THROW_IF( !equilHasConverged, getCatalogName() << " " << getDataContext() << ": hydrostatic pressure initialization failed to converge in region " << region.getName() << "!", - std::runtime_error, getDataContext() ); + geos::RuntimeError, getDataContext() ); } ); // Step 3.4: create hydrostatic pressure table diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseHybridFVM.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseHybridFVM.cpp index 5ae213a31b2..b31b42dcb35 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseHybridFVM.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseHybridFVM.cpp @@ -141,7 +141,7 @@ void SinglePhaseHybridFVM::initializePostInitialConditionsPreSubGroups() GEOS_THROW_IF_LE_MSG( minVal.get(), 0.0, getCatalogName() << " " << getDataContext() << "The transmissibility multipliers used in SinglePhaseHybridFVM must strictly larger than 0.0", - std::runtime_error ); + geos::RuntimeError ); FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); fsManager.forSubGroups< AquiferBoundaryCondition >( [&] ( AquiferBoundaryCondition const & bc ) diff --git a/src/coreComponents/physicsSolvers/multiphysics/CompositionalMultiphaseReservoirAndWells.cpp b/src/coreComponents/physicsSolvers/multiphysics/CompositionalMultiphaseReservoirAndWells.cpp index 425bccfa72c..00e98cfcdcd 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/CompositionalMultiphaseReservoirAndWells.cpp +++ b/src/coreComponents/physicsSolvers/multiphysics/CompositionalMultiphaseReservoirAndWells.cpp @@ -291,7 +291,7 @@ assembleCouplingTerms( real64 const time_n, GEOS_THROW_IF( !Base::m_isWellTransmissibilityComputed, GEOS_FMT( "{} {}: The well transmissibility has not been computed yet", this->getCatalogName(), this->getName() ), - std::runtime_error ); + geos::RuntimeError ); BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags; if( Base::wellSolver()->useTotalMassEquation() ) diff --git a/src/coreComponents/physicsSolvers/multiphysics/CoupledReservoirAndWellsBase.cpp b/src/coreComponents/physicsSolvers/multiphysics/CoupledReservoirAndWellsBase.cpp index fbb8e7fb935..26355f4b610 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/CoupledReservoirAndWellsBase.cpp +++ b/src/coreComponents/physicsSolvers/multiphysics/CoupledReservoirAndWellsBase.cpp @@ -157,7 +157,7 @@ bool validateWellPerforations( PhysicsSolverBase const * const reservoirSolver, GEOS_THROW_IF( !badPerforation.first.empty(), GEOS_FMT( "{}: The well {} has a connection to the region {} which is not targeted by the flow solver", wellSolver->getDataContext(), badPerforation.first, badPerforation.second ), - std::runtime_error, wellSolver->getDataContext() ); + geos::RuntimeError, wellSolver->getDataContext() ); return hasBadPerforations == 0; } diff --git a/src/coreComponents/physicsSolvers/multiphysics/SinglePhaseReservoirAndWells.cpp b/src/coreComponents/physicsSolvers/multiphysics/SinglePhaseReservoirAndWells.cpp index 46cf3257088..acdc445d705 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/SinglePhaseReservoirAndWells.cpp +++ b/src/coreComponents/physicsSolvers/multiphysics/SinglePhaseReservoirAndWells.cpp @@ -249,7 +249,7 @@ assembleCouplingTerms( real64 const time_n, GEOS_THROW_IF( !Base::m_isWellTransmissibilityComputed, GEOS_FMT( "{} {}: The well transmissibility has not been computed yet", this->getCatalogName(), this->getName() ), - std::runtime_error ); + geos::RuntimeError ); this->template forDiscretizationOnMeshTargets<>( domain.getMeshBodies(), [&] ( string const &, MeshLevel const & mesh, diff --git a/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustic/secondOrderEqn/isotropic/AcousticWaveEquationSEM.cpp b/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustic/secondOrderEqn/isotropic/AcousticWaveEquationSEM.cpp index 6190586dded..95cd1f636f0 100644 --- a/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustic/secondOrderEqn/isotropic/AcousticWaveEquationSEM.cpp +++ b/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustic/secondOrderEqn/isotropic/AcousticWaveEquationSEM.cpp @@ -293,7 +293,7 @@ void AcousticWaveEquationSEM::addSourceToRightHandSide( integer const cycleNumbe GEOS_THROW_IF( cycleNumber > sourceValue.size( 0 ), getDataContext() << ": Too many steps compared to array size", - std::runtime_error, getDataContext() ); + geos::RuntimeError, getDataContext() ); forAll< EXEC_POLICY >( sourceConstants.size( 0 ), [=] GEOS_HOST_DEVICE ( localIndex const isrc ) { if( sourceIsAccessible[isrc] == 1 ) @@ -555,7 +555,7 @@ real64 AcousticWaveEquationSEM::computeTimeStep( real64 & dtOut ) } while (counter < 10 && numberIter < nIterMax); - GEOS_THROW_IF( numberIter> nIterMax, "Power Iteration algorithm does not converge", std::runtime_error ); + GEOS_THROW_IF( numberIter> nIterMax, "Power Iteration algorithm does not converge", geos::RuntimeError ); // We use 1.99 instead of 2 to have a 5% margin error real64 dt = 1.99/sqrt( LvArray::math::abs( lambdaNew )); diff --git a/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustoelastic/secondOrderEqn/isotropic/AcousticElasticWaveEquationSEM.cpp b/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustoelastic/secondOrderEqn/isotropic/AcousticElasticWaveEquationSEM.cpp index 9059a3f8a27..b543c6643d5 100644 --- a/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustoelastic/secondOrderEqn/isotropic/AcousticElasticWaveEquationSEM.cpp +++ b/src/coreComponents/physicsSolvers/wavePropagation/sem/acoustoelastic/secondOrderEqn/isotropic/AcousticElasticWaveEquationSEM.cpp @@ -61,7 +61,7 @@ void AcousticElasticWaveEquationSEM::initializePostInitialConditionsPreSubGroups m_interfaceNodesSet.insert( val ); } localIndex const numInterfaceNodes = MpiWrapper::sum( m_interfaceNodesSet.size() ); - GEOS_THROW_IF( numInterfaceNodes == 0, "Failed to compute interface: check xml input (solver order)", std::runtime_error ); + GEOS_THROW_IF( numInterfaceNodes == 0, "Failed to compute interface: check xml input (solver order)", geos::RuntimeError ); m_acousRegions = &(acousSolver->getReference< string_array >( PhysicsSolverBase::viewKeyStruct::targetRegionsString() )); m_elasRegions = &(elasSolver->getReference< string_array >( PhysicsSolverBase::viewKeyStruct::targetRegionsString() )); diff --git a/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/anisotropic/ElasticVTIWaveEquationSEMKernel.hpp b/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/anisotropic/ElasticVTIWaveEquationSEMKernel.hpp index dce27fada16..3b70241a7ec 100644 --- a/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/anisotropic/ElasticVTIWaveEquationSEMKernel.hpp +++ b/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/anisotropic/ElasticVTIWaveEquationSEMKernel.hpp @@ -308,7 +308,7 @@ struct ComputeTimeStep } while (counter < 10 && numberIter < nIterMax); - GEOS_THROW_IF( numberIter> nIterMax, "Power Iteration algorithm does not converge", std::runtime_error ); + GEOS_THROW_IF( numberIter> nIterMax, "Power Iteration algorithm does not converge", RuntimeError ); real64 dt = 1.99/sqrt( LvArray::math::abs( lambdaNew )); diff --git a/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/isotropic/ElasticWaveEquationSEM.cpp b/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/isotropic/ElasticWaveEquationSEM.cpp index 2c16780151b..2b5e34323c7 100644 --- a/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/isotropic/ElasticWaveEquationSEM.cpp +++ b/src/coreComponents/physicsSolvers/wavePropagation/sem/elastic/secondOrderEqn/isotropic/ElasticWaveEquationSEM.cpp @@ -680,7 +680,7 @@ real64 ElasticWaveEquationSEM::computeTimeStep( real64 & dtOut ) } while (counter < 10 && numberIter < nIterMax); - GEOS_THROW_IF( numberIter> nIterMax, "Power Iteration algorithm does not converge", std::runtime_error ); + GEOS_THROW_IF( numberIter> nIterMax, "Power Iteration algorithm does not converge", geos::RuntimeError ); //We use 1.99 instead of 2 to have a 5% margin error real64 dt = 1.99/sqrt( LvArray::math::abs( lambdaNew )); diff --git a/src/coreComponents/schema/schema.xsd b/src/coreComponents/schema/schema.xsd index 0d6554b6eef..6f03bb9ca76 100644 --- a/src/coreComponents/schema/schema.xsd +++ b/src/coreComponents/schema/schema.xsd @@ -463,6 +463,10 @@ + + + + @@ -491,6 +495,10 @@ + + + + @@ -569,6 +577,10 @@ + + + + @@ -581,6 +593,10 @@ + + + + @@ -2740,6 +2756,7 @@ Information output from lower logLevels is added with the desired log level + @@ -2747,6 +2764,7 @@ Information output from lower logLevels is added with the desired log level + @@ -3635,8 +3653,9 @@ Information output from lower logLevels is added with the desired log level +Frequency of pressure update is set in SinglePhase/CompositionalMultiphaseStatistics definition. +Setting cycleFrequency='1' will update the pressure every timestep, note that is a lagged property in constraint propertiesNote the event associated with the statists task must be entered before the solver event. +--> @@ -5028,6 +5047,60 @@ Local- Add jump stabilization on interior of macro elements--> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5368,6 +5441,60 @@ Local- Add jump stabilization on interior of macro elements--> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5912,9 +6039,11 @@ When set to `all` output both convergence & iteration information to a csv.--> + + @@ -6108,6 +6237,19 @@ Information output from lower logLevels is added with the desired log level + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreComponents/schema/schema.xsd.other b/src/coreComponents/schema/schema.xsd.other index bea55da9276..35676a136fc 100644 --- a/src/coreComponents/schema/schema.xsd.other +++ b/src/coreComponents/schema/schema.xsd.other @@ -526,7 +526,7 @@ A field can represent a physical variable. (pressure, temperature, global compos - + @@ -595,6 +595,7 @@ A field can represent a physical variable. (pressure, temperature, global compos + @@ -602,6 +603,7 @@ A field can represent a physical variable. (pressure, temperature, global compos + @@ -1209,6 +1211,17 @@ A field can represent a physical variable. (pressure, temperature, global compos + + + + + + + + + + + @@ -1284,6 +1297,17 @@ A field can represent a physical variable. (pressure, temperature, global compos + + + + + + + + + + + @@ -1452,9 +1476,11 @@ A field can represent a physical variable. (pressure, temperature, global compos + + @@ -1484,9 +1510,11 @@ A field can represent a physical variable. (pressure, temperature, global compos + + @@ -1526,7 +1554,7 @@ A field can represent a physical variable. (pressure, temperature, global compos - + @@ -3559,6 +3587,12 @@ A field can represent a physical variable. (pressure, temperature, global compos + + + + + + @@ -3573,14 +3607,26 @@ A field can represent a physical variable. (pressure, temperature, global compos + + + + + + + + + + + + diff --git a/src/main/main.cpp b/src/main/main.cpp index 14750a4d4a1..5e623c907dc 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -14,8 +14,7 @@ */ // Source includes -#include "common/DataTypes.hpp" -#include "common/format/Format.hpp" +#include "common/logger/Logger.hpp" #include "common/TimingMacros.hpp" #include "common/Units.hpp" #include "mainInterface/initialization.hpp" @@ -74,16 +73,20 @@ int main( int argc, char *argv[] ) basicCleanup(); return 0; } - catch( std::exception const & e ) - { - GEOS_LOG( e.what() ); - if( ErrorLogger::global().isOutputFileEnabled() ) - { - ErrorLogger::global().flushErrorMsg( ErrorLogger::global().currentErrorMsg() ); - } + catch( geos::Exception & e ) + { // GEOS generated exceptions management + ErrorLogger::global().flushErrorMsg( ErrorLogger::global().currentErrorMsg() ); + basicCleanup(); + // lvarray error handler is just program termination LvArray::system::callErrorHandler(); + } + catch( std::exception const & e ) + { // native exceptions management + ErrorLogger::ErrorMsg & errMsg = ErrorLogger::global().currentErrorMsg(); + ErrorLogger::global().flushErrorMsg( errMsg ); basicCleanup(); - std::abort(); + // lvarray error handler is just program termination + LvArray::system::callErrorHandler(); } return 0; } diff --git a/src/pygeosx/pygeosx.cpp b/src/pygeosx/pygeosx.cpp index fff9d7aea9c..3941c74668a 100644 --- a/src/pygeosx/pygeosx.cpp +++ b/src/pygeosx/pygeosx.cpp @@ -119,7 +119,7 @@ static constexpr char const * initializeDocString = "--\n\n" "Initialize GEOSX, this must be the first module call.\n\n" "Should only be called once. All calls after the first will\n" - "raise a `RuntimeError`. To reinitialize GEOSX for a new problem,\n" + "raise a `geos::RuntimeError`. To reinitialize GEOSX for a new problem,\n" "use the `reinit` function.\n" "\n" "Parameters\n"