DeferredLoggingErrorHelpers.hpp
Go to the documentation of this file.
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
28
30
31#include <string>
32#include <exception>
33#include <stdexcept>
34
35// Macro to log an error and 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
54// Macro to log a problem and throw an exception.
55// Idenitical to OPM_DEFLOG_THROW() except for using
56// the "problem" category instead of "error" for the
57// log message. The Exception argument will typically
58// be NumericalProblem.
59//
60// Usage: OPM_DEFLOG_PROBLEM(ExceptionClass, "Error message", DeferredLogger);
61#define OPM_DEFLOG_PROBLEM(Exception, message, deferred_logger) \
62 do { \
63 std::string oss_ = std::string{"["} + __FILE__ + ":" + \
64 std::to_string(__LINE__) + "] " + \
65 message; \
66 deferred_logger.problem(oss_); \
67 throw Exception(oss_); \
68 } while (false)
69
70
71namespace {
72
73void _throw(Opm::ExceptionType::ExcEnum exc_type,
74 const std::string& message,
76{
77 auto global_exc = comm.max(exc_type);
78
79 switch (global_exc) {
81 break;
83 throw std::runtime_error(message);
84 break;
86 throw std::invalid_argument(message);
87 break;
89 throw Opm::NumericalProblem(message);
90 break;
93 throw std::logic_error(message);
94 break;
95 default:
96 throw std::logic_error(message);
97 }
98}
99
100} // anonymous namespace
101
102
103
105 const std::string& message,
107{
108 _throw(exc_type, message, comm);
109}
110
113 const std::string& message,
114 const bool terminal_output,
116{
117 // add exception message to logger in order to display message from all ranks
118 if (exc_type != Opm::ExceptionType::NONE && comm.size() > 1) {
119 deferred_logger.error("[Exception on rank " + std::to_string(comm.rank()) + "]: " + message);
120 }
121 Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(deferred_logger, comm);
122
123 if (terminal_output) {
124 global_deferredLogger.logMessages();
125 }
126 // Now that all messages have been logged, they are automatically
127 // cleared from the global logger, but we must also clear them
128 // from the local logger.
129 deferred_logger.clearMessages();
130 _throw(exc_type, message, comm);
131}
132
133
138#define OPM_BEGIN_PARALLEL_TRY_CATCH() \
139std::string obptc_exc_msg; \
140auto obptc_exc_type = Opm::ExceptionType::NONE; \
141try {
142
146#define OPM_PARALLEL_CATCH_CLAUSE(obptc_exc_type, \
147 obptc_exc_msg) \
148catch (const Opm::NumericalProblem& e){ \
149 obptc_exc_type = Opm::ExceptionType::NUMERICAL_ISSUE; \
150 obptc_exc_msg = e.what(); \
151} catch (const std::runtime_error& e) { \
152 obptc_exc_type = Opm::ExceptionType::RUNTIME_ERROR; \
153 obptc_exc_msg = e.what(); \
154} catch (const std::invalid_argument& e) { \
155 obptc_exc_type = Opm::ExceptionType::INVALID_ARGUMENT; \
156 obptc_exc_msg = e.what(); \
157} catch (const std::logic_error& e) { \
158 obptc_exc_type = Opm::ExceptionType::LOGIC_ERROR; \
159 obptc_exc_msg = e.what(); \
160} catch (const std::exception& e) { \
161 obptc_exc_type = Opm::ExceptionType::DEFAULT; \
162 obptc_exc_msg = e.what(); \
163} catch (...) { \
164 obptc_exc_type = Opm::ExceptionType::DEFAULT; \
165 obptc_exc_msg = "Unknown exception was thrown"; \
166}
167
172#define OPM_END_PARALLEL_TRY_CATCH(prefix, comm) \
173} \
174OPM_PARALLEL_CATCH_CLAUSE(obptc_exc_type, obptc_exc_msg);\
175checkForExceptionsAndThrow(obptc_exc_type, \
176 prefix + obptc_exc_msg, comm);
177
182#define OPM_END_PARALLEL_TRY_CATCH_LOG(obptc_logger, obptc_prefix, obptc_output, comm)\
183} \
184OPM_PARALLEL_CATCH_CLAUSE(obptc_exc_type, obptc_exc_msg); \
185logAndCheckForExceptionsAndThrow(obptc_logger, obptc_exc_type, \
186 obptc_prefix + obptc_exc_msg, obptc_output, comm);
187#endif // OPM_DEFERREDLOGGINGERRORHELPERS_HPP
void logAndCheckForExceptionsAndThrow(Opm::DeferredLogger &deferred_logger, Opm::ExceptionType::ExcEnum exc_type, const std::string &message, const bool terminal_output, Opm::Parallel::Communication comm)
Definition: DeferredLoggingErrorHelpers.hpp:111
void checkForExceptionsAndThrow(Opm::ExceptionType::ExcEnum exc_type, const std::string &message, Opm::Parallel::Communication comm)
Definition: DeferredLoggingErrorHelpers.hpp:104
Definition: DeferredLogger.hpp:57
void clearMessages()
Clear the message container without logging them.
void error(const std::string &tag, const std::string &message)
ExcEnum
Definition: DeferredLogger.hpp:45
@ NONE
Definition: DeferredLogger.hpp:46
@ INVALID_ARGUMENT
Definition: DeferredLogger.hpp:48
@ RUNTIME_ERROR
Definition: DeferredLogger.hpp:47
@ LOGIC_ERROR
Definition: DeferredLogger.hpp:49
@ DEFAULT
Definition: DeferredLogger.hpp:50
@ NUMERICAL_ISSUE
Definition: DeferredLogger.hpp:51
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
Opm::DeferredLogger gatherDeferredLogger(const Opm::DeferredLogger &local_deferredlogger, Parallel::Communication communicator)
Create a global log combining local logs.
std::string to_string(const ConvergenceReport::ReservoirFailure::Type t)