Add error mode DELAYED_EXIT1 to collect all errors

This commit is contained in:
Joakim Hove 2019-01-04 17:12:53 +01:00
parent 23cbe9035b
commit cf42146d84
7 changed files with 52 additions and 27 deletions

View File

@ -7,6 +7,7 @@ set(genkw_SOURCES src/opm/json/JsonObject.cpp
src/opm/parser/eclipse/Deck/DeckOutput.cpp src/opm/parser/eclipse/Deck/DeckOutput.cpp
src/opm/parser/eclipse/Generator/KeywordGenerator.cpp src/opm/parser/eclipse/Generator/KeywordGenerator.cpp
src/opm/parser/eclipse/Generator/KeywordLoader.cpp src/opm/parser/eclipse/Generator/KeywordLoader.cpp
src/opm/parser/eclipse/Parser/ErrorGuard.cpp
src/opm/parser/eclipse/Parser/ParseContext.cpp src/opm/parser/eclipse/Parser/ParseContext.cpp
src/opm/parser/eclipse/Parser/ParserEnums.cpp src/opm/parser/eclipse/Parser/ParserEnums.cpp
src/opm/parser/eclipse/Parser/ParserItem.cpp src/opm/parser/eclipse/Parser/ParserItem.cpp

View File

@ -41,9 +41,9 @@ public:
*/ */
~ErrorGuard(); ~ErrorGuard();
void terminate() const; void terminate() const;
void dump() const;
private: private:
void dump() const;
std::vector<std::pair<std::string, std::string>> error_list; std::vector<std::pair<std::string, std::string>> error_list;
std::vector<std::pair<std::string, std::string>> warning_list; std::vector<std::pair<std::string, std::string>> warning_list;

View File

@ -37,7 +37,8 @@ namespace Opm {
THROW_EXCEPTION = 0, THROW_EXCEPTION = 0,
WARN = 1, WARN = 1,
IGNORE = 2, IGNORE = 2,
EXIT1 = 3 EXIT1 = 3,
DELAYED_EXIT1 = 4
}; };
} }
} }

View File

@ -55,7 +55,7 @@ namespace Opm {
void ErrorGuard::terminate() const { void ErrorGuard::terminate() const {
this->dump(); this->dump();
std::terminate(); std::exit(1);
} }

View File

@ -102,6 +102,8 @@ namespace Opm {
envUpdate( "OPM_ERRORS_IGNORE" , InputError::IGNORE ); envUpdate( "OPM_ERRORS_IGNORE" , InputError::IGNORE );
envUpdate( "OPM_ERRORS_EXIT1", InputError::EXIT1); envUpdate( "OPM_ERRORS_EXIT1", InputError::EXIT1);
envUpdate( "OPM_ERRORS_EXIT", InputError::EXIT1); envUpdate( "OPM_ERRORS_EXIT", InputError::EXIT1);
envUpdate( "OPM_ERRORS_DELAYED_EXIT1", InputError::DELAYED_EXIT1);
envUpdate( "OPM_ERRORS_DELAYED_EXIT", InputError::DELAYED_EXIT1);
} }
@ -117,22 +119,38 @@ namespace Opm {
InputError::Action action = get( errorKey ); InputError::Action action = get( errorKey );
if (action == InputError::WARN) { if (action == InputError::IGNORE) {
OpmLog::warning(msg); errors.addWarning(errorKey, msg);
return; return;
} }
else if (action == InputError::THROW_EXCEPTION) { if (action == InputError::WARN) {
OpmLog::warning(msg);
errors.addWarning(errorKey, msg);
return;
}
if (action == InputError::THROW_EXCEPTION) {
OpmLog::error(msg); OpmLog::error(msg);
// If we decide to throw immediately - we clear the error stack to
// make sure the error object does not terminate the application
// when it goes out of scope.
errors.clear();
throw std::invalid_argument(errorKey + ": " + msg); throw std::invalid_argument(errorKey + ": " + msg);
} }
else if (action == InputError::EXIT1) { if (action == InputError::EXIT1) {
OpmLog::error(msg); OpmLog::error(msg);
std::cerr << "A fatal error has occured and the application will stop." << std::endl; std::cerr << "A fatal error has occured and the application will stop." << std::endl;
std::cerr << msg << std::endl; std::cerr << msg << std::endl;
std::exit(1); std::exit(1);
} }
if (action == InputError::DELAYED_EXIT1) {
OpmLog::error(msg);
errors.addError(errorKey, msg);
return;
}
} }
void ParseContext::handleUnknownKeyword(const std::string& keyword, ErrorGuard& errors) const { void ParseContext::handleUnknownKeyword(const std::string& keyword, ErrorGuard& errors) const {

View File

@ -7,19 +7,19 @@
#include <opm/parser/eclipse/Parser/ParseContext.hpp> #include <opm/parser/eclipse/Parser/ParseContext.hpp>
void exit1() { void exit1(Opm::InputError::Action action) {
const char * deckString = const char * deckString =
"RUNSPEC\n" "RUNSPEC\n"
"DIMENS\n" "DIMENS\n"
" 10 10 10 10 /n" " 10 10 10 10 /n"
"\n"; "\n";
Opm::ParseContext parseContext; Opm::ParseContext parseContext;
Opm::Parser parser; Opm::Parser parser;
Opm::ErrorGuard errors; Opm::ErrorGuard errors;
parseContext.update(Opm::ParseContext::PARSE_EXTRA_DATA , Opm::InputError::EXIT1 ); parseContext.update(Opm::ParseContext::PARSE_EXTRA_DATA , action);
parser.parseString( deckString , parseContext, errors ); parser.parseString( deckString , parseContext, errors );
} }
@ -31,21 +31,26 @@ void exit1() {
this test is implemented without the BOOST testing framework. this test is implemented without the BOOST testing framework.
*/ */
int main() { void test_exit(Opm::InputError::Action action) {
pid_t pid = fork(); pid_t pid = fork();
if (pid == 0) if (pid == 0)
exit1(); exit1(action);
int wait_status; int wait_status;
waitpid(pid, &wait_status, 0); waitpid(pid, &wait_status, 0);
if (WIFEXITED(wait_status)) if (WIFEXITED(wait_status)) {
/* /*
We *want* the child process to terminate with status exit(1), here we We *want* the child process to terminate with status exit(1), i.e. if
capture the exit status of the child process, and then we invert that the exit status is 0 we fail the complete test with exit(1).
and return the inverted status as the status of the complete test.
*/ */
std::exit( !WEXITSTATUS(wait_status) ); if (WEXITSTATUS(wait_status) == 0)
else std::exit(EXIT_FAILURE);
} else
std::exit(EXIT_FAILURE); std::exit(EXIT_FAILURE);
} }
int main(int argc, char ** argv) {
test_exit(Opm::InputError::Action::EXIT1);
test_exit(Opm::InputError::Action::DELAYED_EXIT1);
}

View File

@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(noNNC)
BOOST_AUTO_TEST_CASE(readDeck) BOOST_AUTO_TEST_CASE(readDeck)
{ {
Parser parser; Parser parser;
auto deck = parser.parseFile(pathprefix() + "NNC/noNNC.DATA"); auto deck = parser.parseFile(pathprefix() + "EDITNNC/EDITNNC.DATA");
EclipseState eclipseState(deck); EclipseState eclipseState(deck);
const auto& editnnc = eclipseState.getInputEDITNNC(); const auto& editnnc = eclipseState.getInputEDITNNC();
BOOST_CHECK(!editnnc.empty()); BOOST_CHECK(!editnnc.empty());