My Project
OpmInputError.hpp
1 /*
2  Copyright 2020 Equinor ASA.
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 #ifndef OPM_ERROR_HPP
20 #define OPM_ERROR_HPP
21 
22 #include <stdexcept>
23 #include <string>
24 #include <vector>
25 
26 #include <opm/common/OpmLog/KeywordLocation.hpp>
27 
28 namespace Opm {
29 
30 /*
31  The OpmInputError is a custom exception class which can be used to signal
32  errors in input handling. The importance of the OpmInputError exception is
33  *not* the tecnical functionality it provides, but rather the convention
34  surrounding it, when and how it should be used.
35 
36  The OpmInputError should be used in situations which are "close to user
37  input", the root cause can either be incorrect user input or a bug/limitation
38  in opm. OpmInputError should only be used in situations where we have a good
39  understanding of the underlying issue, and can provide a good error message.
40 
41  The local error handling should be complete when the OpmInputError is
42  instantiated, it should not be caught and rethrown in order to e.g. add
43  additional context or log messages. In order to avoid inadvertendly catching
44  this exception in a catch all block.
45 */
46 
47 
48 
49 class OpmInputError : public std::exception {
50 public:
51  /*
52  The message string will be used as format string in the fmt::format()
53  function as, and optional {} markers can be used to inject keyword,
54  filename and linenumber into the final what() message. The placeholders
55  must use named arguments
56 
57  {keyword} -> loc.keyword
58  {file} -> loc.filename
59  {line} -> loc.lineno
60 
61  additionally, the message can contain any number of positional
62  arguments to add further context to the message.
63 
64  KeywordLocation loc("KW", "file.inc", 100);
65  OpmInputError("Error at line {line} in file {file} - keyword: {keyword} ignored", location);
66  OpmInputError("Error at line {line} in file {file} - keyword: {keyword} has invalid argument {}", invalid_argument);
67  */
68 
69  template<typename ... Args>
70  OpmInputError(const std::string& reason, const KeywordLocation& location, const Args& ...furtherLocations)
71  : locations { location, furtherLocations... }
72  , m_what {
73  locations.size() == 1
74  ? formatSingle(reason, locations[0])
75  : formatMultiple(reason, locations)
76  }
77  { }
78 
79  /*
80  Allows for the initialisation of an OpmInputError from another exception.
81 
82  Usage:
83 
84  try {
85  .
86  .
87  .
88  } catch (const Opm::OpmInputError&) {
89  throw;
90  } catch (const std::exception& e) {
91  std::throw_with_nested(Opm::OpmInputError(e, location));
92  }
93  */
94  OpmInputError(const std::exception& error, const KeywordLocation& location)
95  : locations { location }
96  , m_what { formatException(error, locations[0]) }
97  { }
98 
99  const char * what() const throw()
100  {
101  return this->m_what.c_str();
102  }
103 
104 
105  static std::string format(const std::string& msg_format, const KeywordLocation& loc);
106 
107 private:
108  // The location member is here for debugging; depending on the msg_fmt
109  // passed in the constructor we might not have captured all the information
110  // in the location argument passed to the constructor.
111  std::vector<KeywordLocation> locations;
112 
113  std::string m_what;
114 
115  static std::string formatException(const std::exception& e, const KeywordLocation& loc);
116  static std::string formatSingle(const std::string& reason, const KeywordLocation&);
117  static std::string formatMultiple(const std::string& reason, const std::vector<KeywordLocation>&);
118 };
119 
120 }
121 #endif
Definition: KeywordLocation.hpp:27
Definition: OpmInputError.hpp:49
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:29