My Project
Loading...
Searching...
No Matches
DeferredLoggingErrorHelpers.hpp
1/*
2 Copyright 2019 SINTEF Digital, Mathematics and Cybernetics.
3
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19*/
20
21#ifndef OPM_DEFERREDLOGGINGERRORHELPERS_HPP
22#define OPM_DEFERREDLOGGINGERRORHELPERS_HPP
23
24#include <opm/common/Exceptions.hpp>
25
26#include <opm/simulators/utils/DeferredLogger.hpp>
27#include <opm/simulators/utils/gatherDeferredLogger.hpp>
28
29#include <opm/simulators/utils/ParallelCommunication.hpp>
30
31#include <string>
32#include <exception>
33#include <stdexcept>
34
35// Macro to throw an exception.
36// Inspired by ErrorMacros.hpp in opm-common.
37// NOTE: For this macro to work, the
38// exception class must exhibit a constructor with the signature
39// (const std::string &message). Since this condition is not fulfilled
40// for the std::exception, you should use this macro with some
41// exception class derived from either std::logic_error or
42// std::runtime_error.
43//
44// Usage: OPM_DEFLOG_THROW(ExceptionClass, "Error message", DeferredLogger);
45#define OPM_DEFLOG_THROW(Exception, message, deferred_logger) \
46 do { \
47 std::string oss_ = std::string{"["} + __FILE__ + ":" + \
48 std::to_string(__LINE__) + "] " + \
49 message; \
50 deferred_logger.error(oss_); \
51 throw Exception(oss_); \
52 } while (false)
53
54namespace {
55
56void _throw(Opm::ExceptionType::ExcEnum exc_type,
57 const std::string& message,
58 Opm::Parallel::Communication comm)
59{
60 auto global_exc = comm.max(exc_type);
61
62 switch (global_exc) {
63 case Opm::ExceptionType::NONE:
64 break;
65 case Opm::ExceptionType::RUNTIME_ERROR:
66 throw std::runtime_error(message);
67 break;
68 case Opm::ExceptionType::INVALID_ARGUMENT:
69 throw std::invalid_argument(message);
70 break;
71 case Opm::ExceptionType::NUMERICAL_ISSUE:
72 throw Opm::NumericalProblem(message);
73 break;
74 case Opm::ExceptionType::DEFAULT:
75 case Opm::ExceptionType::LOGIC_ERROR:
76 throw std::logic_error(message);
77 break;
78 default:
79 throw std::logic_error(message);
80 }
81}
82
83} // anonymous namespace
84
85
86
87inline void checkForExceptionsAndThrow(Opm::ExceptionType::ExcEnum exc_type,
88 const std::string& message,
89 Opm::Parallel::Communication comm)
90{
91 _throw(exc_type, message, comm);
92}
93
94inline void logAndCheckForExceptionsAndThrow(Opm::DeferredLogger& deferred_logger,
95 Opm::ExceptionType::ExcEnum exc_type,
96 const std::string& message,
97 const bool terminal_output,
98 Opm::Parallel::Communication comm)
99{
100 Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(deferred_logger, comm);
101
102 if (terminal_output) {
103 global_deferredLogger.logMessages();
104 }
105 // Now that all messages have been logged, they are automatically
106 // cleared from the global logger, but we must also clear them
107 // from the local logger.
108 deferred_logger.clearMessages();
109 _throw(exc_type, message, comm);
110}
111
112
117#define OPM_BEGIN_PARALLEL_TRY_CATCH() \
118std::string obptc_exc_msg; \
119auto obptc_exc_type = Opm::ExceptionType::NONE; \
120try {
121
125#define OPM_PARALLEL_CATCH_CLAUSE(obptc_exc_type, \
126 obptc_exc_msg) \
127catch (const Opm::NumericalProblem& e){ \
128 obptc_exc_type = Opm::ExceptionType::NUMERICAL_ISSUE; \
129 obptc_exc_msg = e.what(); \
130} catch (const std::runtime_error& e) { \
131 obptc_exc_type = Opm::ExceptionType::RUNTIME_ERROR; \
132 obptc_exc_msg = e.what(); \
133} catch (const std::invalid_argument& e) { \
134 obptc_exc_type = Opm::ExceptionType::INVALID_ARGUMENT; \
135 obptc_exc_msg = e.what(); \
136} catch (const std::logic_error& e) { \
137 obptc_exc_type = Opm::ExceptionType::LOGIC_ERROR; \
138 obptc_exc_msg = e.what(); \
139} catch (const std::exception& e) { \
140 obptc_exc_type = Opm::ExceptionType::DEFAULT; \
141 obptc_exc_msg = e.what(); \
142} catch (...) { \
143 obptc_exc_type = Opm::ExceptionType::DEFAULT; \
144 obptc_exc_msg = "Unknown exception was thrown"; \
145}
146
151#define OPM_END_PARALLEL_TRY_CATCH(prefix, comm) \
152} \
153OPM_PARALLEL_CATCH_CLAUSE(obptc_exc_type, obptc_exc_msg);\
154checkForExceptionsAndThrow(obptc_exc_type, \
155 prefix + obptc_exc_msg, comm);
156
161#define OPM_END_PARALLEL_TRY_CATCH_LOG(obptc_logger, obptc_prefix, obptc_output, comm)\
162} \
163OPM_PARALLEL_CATCH_CLAUSE(obptc_exc_type, obptc_exc_msg); \
164logAndCheckForExceptionsAndThrow(obptc_logger, obptc_exc_type, \
165 obptc_prefix + obptc_exc_msg, obptc_output, comm);
166#endif // OPM_DEFERREDLOGGINGERRORHELPERS_HPP
Definition AquiferInterface.hpp:35
Definition DeferredLogger.hpp:57
void logMessages()
Log all messages to the OpmLog backends, and clear the message container.
Definition DeferredLogger.cpp:85
void clearMessages()
Clear the message container without logging them.
Definition DeferredLogger.cpp:93
Opm::DeferredLogger gatherDeferredLogger(const Opm::DeferredLogger &local_deferredlogger, Opm::Parallel::Communication)
Create a global log combining local logs.
Definition gatherDeferredLogger.cpp:168