MeshKernel
Exceptions.hpp
1 //---- GPL ---------------------------------------------------------------------
2 //
3 // Copyright (C) Stichting Deltares, 2011-2023.
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation version 3.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // contact: delft3d.support@deltares.nl
18 // Stichting Deltares
19 // P.O. Box 177
20 // 2600 MH Delft, The Netherlands
21 //
22 // All indications and logos of, and references to, "Delft3D" and "Deltares"
23 // are registered trademarks of Stichting Deltares, and remain the property of
24 // Stichting Deltares. All rights reserved.
25 //
26 //------------------------------------------------------------------------------
27 
28 #pragma once
29 
30 #include "MeshKernel/Constants.hpp"
31 #include "MeshKernel/Definitions.hpp"
32 #include "MeshKernel/Formatting.hpp"
33 
34 #include <algorithm>
35 #include <exception>
36 #include <source_location>
37 #include <sstream>
38 #include <stdexcept>
39 #include <string>
40 #include <string_view>
41 
42 #define STRINGIFY(str) #str
43 #define TO_STR_LITERAL(str) STRINGIFY(str)
44 
45 namespace meshkernel
46 {
47 
49  // Note: Do not change the values. This has an impact on the front-end.
50  // To add a new code, append and set to the highest existing value incremented by 1.
51  enum ExitCode
52  {
53  Success = 0,
63  };
64 
67  {
68  public:
72  ErrorCategory(std::string_view name,
73  ExitCode exit_code)
74  : m_name(name),
75  m_exit_code{exit_code}
76  {
77  }
78 
81  [[nodiscard]] std::string_view Name() const { return m_name; }
82 
85  [[nodiscard]] ExitCode Code() const { return m_exit_code; }
86 
87  private:
88  std::string_view m_name;
89  ExitCode m_exit_code;
90  };
91 
93  class FormatString final
94  {
95  public:
99  FormatString(const char* const format_string,
100  std::source_location const& source_location = std::source_location::current())
101  : m_format_string(format_string),
102  m_source_location(source_location)
103  {
104  }
105 
109  FormatString(std::string_view message,
110  std::source_location const& source_location = std::source_location::current())
111  : m_format_string(message),
112  m_source_location(source_location)
113  {
114  }
115 
119  FormatString(std::string const& message,
120  std::source_location const& source_location = std::source_location::current())
121  : m_format_string(message),
122  m_source_location(source_location)
123  {
124  }
125 
128  [[nodiscard]] std::string_view String() const { return m_format_string; }
129 
132  [[nodiscard]] std::source_location const& SourceLocation() const { return m_source_location; }
133 
134  private:
135  std::string_view m_format_string;
136 
137  std::source_location m_source_location;
138  };
139 
141  class MeshKernelError : public std::exception
142  {
143  public:
147  template <typename... Args>
148  MeshKernelError(FormatString const& format_string, Args&&... args)
149  : m_what(),
150  m_source_location(format_string.SourceLocation())
151  {
152  if (sizeof...(args) == 0)
153  {
154  m_formatted_message = format_string.String();
155  }
156  else
157  {
158  m_formatted_message = fmt_ns::vformat(format_string.String(), fmt_ns::make_format_args(args...));
159  }
160  }
161 
163  virtual ~MeshKernelError() = default;
164 
167  const char* what() const noexcept override
168  {
169 #if HAVE_SRC_LOC_IN_ERR_MSGS
170  m_what = fmt_ns::format("Exception of type '{}' in {} ({}:{}) {}: {}\n",
171  Category().Name(),
172  StrippedFilePath(),
173  m_source_location.line(),
174  m_source_location.column(),
175  m_source_location.function_name(),
176  FormattedMessage());
177 #else
178  m_what = fmt_ns::format("Exception of type '{}': {}\n",
179  Category().Name(),
180  FormattedMessage());
181 #endif
182  return m_what.c_str();
183  }
184 
187  [[nodiscard]] ExitCode Code() const { return Category().Code(); }
188 
189  protected:
192  [[nodiscard]] virtual ErrorCategory Category() const
193  {
194  return {"MeshKernelError", ExitCode::MeshKernelErrorCode};
195  }
196 
198  [[nodiscard]] virtual std::string FormattedMessage() const { return m_formatted_message; }
199 
200  private:
201  std::string m_formatted_message;
202 
203  mutable std::string m_what;
204 
205  std::source_location m_source_location;
206 
209  [[nodiscard]] std::string StrippedFilePath() const
210  {
211  std::string path = m_source_location.file_name();
212 #ifdef CMAKE_SRC_DIR
213  std::string path_to_erase(TO_STR_LITERAL(CMAKE_SRC_DIR));
214 #ifdef _WIN32
215  std::replace(path_to_erase.begin(), path_to_erase.end(), '/', '\\');
216 #endif
217  if (size_t pos = path.find(path_to_erase); pos != std::string::npos)
218  {
219  // erase including the trailing slash
220  path.erase(pos, path_to_erase.length() + 1);
221 #ifdef _WIN32
222  std::replace(path.begin(), path.end(), '\\', '/');
223 #endif
224  }
225 #endif
226  return path;
227  }
228  };
229 
232  {
233  public:
236 
237  private:
240  [[nodiscard]] ErrorCategory Category() const override
241  {
242  return {"NotImplementedError", ExitCode::NotImplementedErrorCode};
243  }
244  };
245 
247  class AlgorithmError final : public MeshKernelError
248  {
249  public:
252 
253  private:
256  [[nodiscard]] ErrorCategory Category() const override
257  {
258  return {"AlgorithmError", ExitCode::AlgorithmErrorCode};
259  }
260  };
261 
266  class ConstraintError final : public MeshKernelError
267  {
268  public:
271 
272  private:
275  [[nodiscard]] ErrorCategory Category() const override
276  {
277  return {"ConstraintError", ExitCode::ConstraintErrorCode};
278  }
279  };
280 
282  class MeshGeometryError final : public MeshKernelError
283  {
284  public:
290  template <typename... Args>
292  Location mesh_location,
293  FormatString const& format_string,
294  Args&&... args)
295  : MeshKernelError(format_string, std::forward<Args>(args)...),
296  m_mesh_index(mesh_index),
297  m_mesh_location(mesh_location)
298  {
299  }
300 
303  [[nodiscard]] meshkernel::UInt MeshIndex() const { return m_mesh_index; }
304 
307  [[nodiscard]] Location MeshLocation() const { return m_mesh_location; }
308 
309  private:
312  [[nodiscard]] ErrorCategory Category() const override
313  {
314  return {"MeshGeometryError", ExitCode::MeshGeometryErrorCode};
315  }
316 
318  [[nodiscard]] std::string FormattedMessage() const override
319  {
320  return fmt_ns::format("Error occurred at index {} (location: {}). {}",
321  m_mesh_index,
322  LocationToString.at(m_mesh_location),
324  }
325 
326  meshkernel::UInt m_mesh_index;
327  Location m_mesh_location;
328  };
329 
331  class LinearAlgebraError final : public MeshKernelError
332  {
333  public:
336 
337  private:
340  [[nodiscard]] ErrorCategory Category() const override
341  {
342  return {"LinearAlgebraError", ExitCode::LinearAlgebraErrorCode};
343  }
344  };
345 
347  class RangeError final : public MeshKernelError
348  {
349  public:
352 
353  private:
356  [[nodiscard]] ErrorCategory Category() const override
357  {
358  return {"RangeError", ExitCode::RangeErrorCode};
359  }
360  };
361 
362 } // namespace meshkernel
meshkernel::NotImplementedError
A class for throwing not implemented exceptions.
Definition: Exceptions.hpp:231
meshkernel::MeshKernelError::FormattedMessage
virtual std::string FormattedMessage() const
Returns the message.
Definition: Exceptions.hpp:198
meshkernel::MeshKernelError::Category
virtual ErrorCategory Category() const
Returns the error category.
Definition: Exceptions.hpp:192
meshkernel::ConstraintErrorCode
@ ConstraintErrorCode
Constraint error.
Definition: Exceptions.hpp:57
meshkernel::MeshGeometryError::MeshIndex
meshkernel::UInt MeshIndex() const
Returns the invalid index.
Definition: Exceptions.hpp:303
meshkernel::FormatString::FormatString
FormatString(std::string const &message, std::source_location const &source_location=std::source_location::current())
Class constructor.
Definition: Exceptions.hpp:119
meshkernel::ErrorCategory::Code
ExitCode Code() const
Return the exit code of the error category.
Definition: Exceptions.hpp:85
meshkernel::ErrorCategory::ErrorCategory
ErrorCategory(std::string_view name, ExitCode exit_code)
Class constructor.
Definition: Exceptions.hpp:72
meshkernel::FormatString::SourceLocation
std::source_location const & SourceLocation() const
Returns the source location.
Definition: Exceptions.hpp:132
meshkernel::MeshKernelError::MeshKernelError
MeshKernelError(FormatString const &format_string, Args &&... args)
Class constructor.
Definition: Exceptions.hpp:148
meshkernel::StdLibExceptionCode
@ StdLibExceptionCode
Standrad library exception.
Definition: Exceptions.hpp:61
meshkernel::MeshKernelError::what
const char * what() const noexcept override
Returns the explanatory string of the error.
Definition: Exceptions.hpp:167
meshkernel::RangeErrorCode
@ RangeErrorCode
Range error.
Definition: Exceptions.hpp:60
meshkernel::Location
Location
Mesh locations enumeration.
Definition: Definitions.hpp:74
meshkernel::LinearAlgebraError
A class for throwing linear algebra exceptions.
Definition: Exceptions.hpp:331
meshkernel::AlgorithmErrorCode
@ AlgorithmErrorCode
Algorithm error.
Definition: Exceptions.hpp:56
meshkernel::UnknownExceptionCode
@ UnknownExceptionCode
Unknown exception.
Definition: Exceptions.hpp:62
meshkernel::MeshGeometryErrorCode
@ MeshGeometryErrorCode
Geometry error.
Definition: Exceptions.hpp:58
meshkernel
Contains the logic of the C++ static library.
Definition: AveragingInterpolation.hpp:36
meshkernel::MeshGeometryError
A class for throwing mesh geometry errors.
Definition: Exceptions.hpp:282
meshkernel::MeshGeometryError::MeshGeometryError
MeshGeometryError(meshkernel::UInt mesh_index, Location mesh_location, FormatString const &format_string, Args &&... args)
Class constructor.
Definition: Exceptions.hpp:291
meshkernel::LinearAlgebraErrorCode
@ LinearAlgebraErrorCode
Linear algebra error.
Definition: Exceptions.hpp:59
meshkernel::UInt
std::uint32_t UInt
Integer type used when indexing mesh graph entities.
Definition: Definitions.hpp:38
meshkernel::MeshKernelErrorCode
@ MeshKernelErrorCode
MehKernel error.
Definition: Exceptions.hpp:54
meshkernel::AlgorithmError
A class for throwing algorithm exceptions.
Definition: Exceptions.hpp:247
meshkernel::MeshKernelError::Code
ExitCode Code() const
Returns the exit code.
Definition: Exceptions.hpp:187
meshkernel::FormatString::FormatString
FormatString(const char *const format_string, std::source_location const &source_location=std::source_location::current())
Class constructor.
Definition: Exceptions.hpp:99
meshkernel::RangeError
A class for throwing range error exceptions.
Definition: Exceptions.hpp:347
meshkernel::ExitCode
ExitCode
Enumeration of exit codes.
Definition: Exceptions.hpp:51
meshkernel::MeshKernelError
A class for throwing general MeshKernel exceptions.
Definition: Exceptions.hpp:141
meshkernel::ErrorCategory
Contains error category information.
Definition: Exceptions.hpp:66
meshkernel::NotImplementedErrorCode
@ NotImplementedErrorCode
Not implemented error.
Definition: Exceptions.hpp:55
meshkernel::FormatString::String
std::string_view String() const
Returns the format string.
Definition: Exceptions.hpp:128
meshkernel::FormatString::FormatString
FormatString(std::string_view message, std::source_location const &source_location=std::source_location::current())
Class constructor.
Definition: Exceptions.hpp:109
meshkernel::MeshKernelError::~MeshKernelError
virtual ~MeshKernelError()=default
Class destructor.
meshkernel::ConstraintError
An exception class thrown when an attempt is made that violates a range constraint.
Definition: Exceptions.hpp:266
meshkernel::FormatString
Manages the format string and source location.
Definition: Exceptions.hpp:93
meshkernel::Success
@ Success
Success.
Definition: Exceptions.hpp:53
meshkernel::MeshGeometryError::MeshLocation
Location MeshLocation() const
Returns the mesh location.
Definition: Exceptions.hpp:307
meshkernel::ErrorCategory::Name
std::string_view Name() const
Returns the name of the error category.
Definition: Exceptions.hpp:81