mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
mxException.hpp
Go to the documentation of this file.
1 /** \file mxException.hpp
2  * \author Jared R. Males (jaredmales@gmail.com)
3  * \brief Declares and defines the mxlib exception class.
4  * \ingroup error_handling_files
5  *
6 */
7 
8 //***********************************************************************//
9 // Copyright 2015, 2016, 2017 Jared R. Males (jaredmales@gmail.com)
10 //
11 // This file is part of mxlib.
12 //
13 // mxlib is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // mxlib is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 //***********************************************************************//
26 
27 #ifndef __mxException__
28 #define __mxException__
29 
30 #include <exception>
31 #include <sstream>
32 
33 #include "mxError.hpp"
34 
35 namespace mx
36 {
37 namespace err
38 {
39 
40 /// The mxlib exception class
41 /** Provides a rich error report via the standard what().
42  * \ingroup exceptions
43  */
44 class mxException : public std::exception
45 {
46 
47 protected:
48  ///Contains the what() string
49  char m_whatstr[4096];
50 
51  ///The source of the exception, such as stdlib or cfitisio or the function name
52  std::string m_source {""};
53 
54  ///The mxlib error code
55  int m_code {0};
56 
57  ///The name of the error code
58  std::string m_codeName {""};
59 
60  ///The errno error code (only used if non-zero)
61  int m_errno {0};
62 
63  ///The source file where the exception originated
64  std::string m_file {""};
65 
66  ///The line number of the file where the exception originated
67  int m_line {0};
68 
69  ///The long explanation of the error
70  std::string m_explanation {""};
71 
72 public:
73 
74  ///Default constructor
75  mxException () noexcept
76  {
77  build_what();
78  }
79 
80  ///Copy constructor
81  mxException (const mxException & e) noexcept : m_source(e.m_source), m_code(e.m_code), m_codeName(e.m_codeName), m_file(e.m_file), m_line(e.m_line), m_explanation(e.m_explanation)
82  {
83  build_what();
84  }
85 
86  ///Construct and fill in each of the values, except errno
87  mxException( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
88  const int & ec, ///< [in] the error code
89  const std::string & emnem, ///< [in] the name of the error code
90  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
91  const int & line, ///< [in] the line number where the exception was thrown
92  const std::string & expl ///< [in] the explanation for why the exception was thrown
93  ) : m_source(esrc), m_code(ec), m_codeName(emnem), m_errno(0), m_file(efile), m_line(line), m_explanation(expl)
94  {
95  build_what();
96  }
97 
98  ///Construct and fill in each of the values, including errno
99  mxException( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
100  const int & ec, ///< [in] the error code
101  const std::string & emnem, ///< [in] the name of the error code
102  const int & en, ///< [in] the value of errno
103  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
104  const int & line, ///< [in] the line number where the exception was thrown
105  const std::string & expl ///< [in] the explanation for why the exception was thrown
106  ) : m_source(esrc), m_code(ec), m_codeName(emnem), m_errno(en), m_file(efile), m_line(line), m_explanation(expl)
107  {
108  build_what();
109  }
110 
111  ///Assignment operator
112  mxException & operator=(const mxException & e) noexcept
113  {
114  m_source = e.m_source;
115  m_code = e.m_code;
116  m_codeName = e.m_codeName;
117  m_errno = e.m_errno;
118  m_file = e.m_file;
119  m_line = e.m_line;
120  m_explanation = e.m_explanation;
121 
122  build_what();
123 
124  return *this;
125  }
126 
127  ///Destructor
128  virtual ~mxException() throw()
129  {
130  }
131 
132  ///Build the what string.
133  /** Must be called after updating any values, since the what() method is const const.
134  */
135  virtual void build_what()
136  {
137  std::ostringstream s;
138  s.str("");
139 
140  if(m_explanation != "") s << " " << m_explanation;
141  if(m_source != "") s << "\n source: " << m_source;
142  if(m_code != 0)
143  {
144  s << "\n code: " << m_code;
145  if(m_codeName != "") s << " ("<< m_codeName << ")";
146  }
147  if(m_errno != 0)
148  {
149  s << "\n errno: " << m_errno << " (" << errno_CodeToName(m_errno) << ")";
150  }
151  if(m_file != "") s << "\n in file: " << m_file;
152  if(m_line != 0) s << "\n at line: " << m_line;
153 
154  if(m_errno != 0)
155  {
156  s << "\n " << strerror(m_errno);
157  }
158  snprintf(m_whatstr, sizeof(m_whatstr), "%s", s.str().c_str());
159  }
160 
161  ///Return the details of the exception as a single string.
162  virtual const char * what() const noexcept
163  {
164  return m_whatstr;
165  }
166 
167 };
168 
169 /// mxException for invalid arguments
170 /**
171  * \ingroup exceptions
172  */
173 class invalidarg : public mxException
174 {
175 public:
176  invalidarg( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
177  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
178  const int & line, ///< [in] the line number where the exception was thrown
179  const std::string & expl ///< [in] the explanation for why the exception was thrown
180  ) : mxException(esrc, MXE_INVALIDARG,MXE_INVALIDARG_NAME, efile, line, expl)
181  {
182  }
183 };
184 
185 /// mxException for invalid config settings
186 /**
187  * \ingroup exceptions
188  */
189 class invalidconfig : public mxException
190 {
191 public:
192  invalidconfig( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
193  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
194  const int & line, ///< [in] the line number where the exception was thrown
195  const std::string & expl ///< [in] the explanation for why the exception was thrown
196  ) : mxException(esrc, MXE_INVALIDCONFIG,MXE_INVALIDCONFIG_NAME, efile, line, expl)
197  {
198  }
199 };
200 
201 /// mxException for not implemented features
202 /**
203  * \ingroup exceptions
204  */
205 class notimpl : public mxException
206 {
207 public:
208  notimpl( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
209  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
210  const int & line, ///< [in] the line number where the exception was thrown
211  const std::string & expl ///< [in] the explanation for why the exception was thrown
212  ) : mxException(esrc, MXE_NOTIMPL,MXE_NOTIMPL_NAME, efile, line, expl)
213  {
214  }
215 };
216 
217 /// mxException for parameters which aren't set
218 /**
219  * \ingroup exceptions
220  */
221 class paramnotset : public mxException
222 {
223 public:
224  paramnotset( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
225  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
226  const int & line, ///< [in] the line number where the exception was thrown
227  const std::string & expl ///< [in] the explanation for why the exception was thrown
228  ) : mxException(esrc, MXE_PARAMNOTSET,MXE_PARAMNOTSET_NAME, efile, line, expl)
229  {
230  }
231 };
232 
233 /// mxException for a size error
234 /**
235  * \ingroup exceptions
236  */
237 class sizeerr : public mxException
238 {
239 public:
240  sizeerr( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
241  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
242  const int & line, ///< [in] the line number where the exception was thrown
243  const std::string & expl ///< [in] the explanation for why the exception was thrown
244  ) : mxException(esrc, MXE_SIZEERR,MXE_SIZEERR_NAME, efile, line, expl)
245  {
246  }
247 };
248 
249 /// mxException for an allocation error
250 /**
251  * \ingroup exceptions
252  */
253 class allocerr : public mxException
254 {
255 public:
256  allocerr( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
257  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
258  const int & line, ///< [in] the line number where the exception was thrown
259  const std::string & expl ///< [in] the explanation for why the exception was thrown
260  ) : mxException(esrc, MXE_ALLOCERR,MXE_ALLOCERR_NAME, efile, line, expl)
261  {
262  }
263 };
264 
265 /// mxException for errors on opening a file
266 /**
267  * \ingroup exceptions
268  */
269 class fileoerr : public mxException
270 {
271 public:
272  fileoerr( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
273  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
274  const int & line, ///< [in] the line number where the exception was thrown
275  const std::string & expl ///< [in] the explanation for why the exception was thrown
276  ) : mxException(esrc, MXE_FILEOERR,MXE_FILEOERR_NAME, efile, line, expl)
277  {
278  }
279  fileoerr( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
280  const int & en, ///< [in] the value of errno
281  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
282  const int & line, ///< [in] the line number where the exception was thrown
283  const std::string & expl ///< [in] the explanation for why the exception was thrown
284  ) : mxException(esrc, MXE_FILEOERR,MXE_FILEOERR_NAME, en, efile, line, expl)
285  {
286  }
287 };
288 
289 /// mxException for errors reading from a file
290 /**
291  * \ingroup exceptions
292  */
293 class filererr : public mxException
294 {
295 public:
296  filererr( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
297  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
298  const int & line, ///< [in] the line number where the exception was thrown
299  const std::string & expl ///< [in] the explanation for why the exception was thrown
300  ) : mxException(esrc, MXE_FILERERR,MXE_FILERERR_NAME, efile, line, expl)
301  {
302  }
303  filererr( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
304  const int & en, ///< [in] the value of errno
305  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
306  const int & line, ///< [in] the line number where the exception was thrown
307  const std::string & expl ///< [in] the explanation for why the exception was thrown
308  ) : mxException(esrc, MXE_FILERERR,MXE_FILERERR_NAME, en, efile, line, expl)
309  {
310  }
311 };
312 
313 /// mxException for errors writing to a file
314 /**
315  * \ingroup exceptions
316  */
317 class filewerr : public mxException
318 {
319 public:
320  filewerr( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
321  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
322  const int & line, ///< [in] the line number where the exception was thrown
323  const std::string & expl ///< [in] the explanation for why the exception was thrown
324  ) : mxException(esrc, MXE_FILEWERR,MXE_FILEWERR_NAME, efile, line, expl)
325  {
326  }
327  filewerr( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
328  const int & en, ///< [in] the value of errno
329  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
330  const int & line, ///< [in] the line number where the exception was thrown
331  const std::string & expl ///< [in] the explanation for why the exception was thrown
332  ) : mxException(esrc, MXE_FILEWERR,MXE_FILEWERR_NAME, en, efile, line, expl)
333  {
334  }
335 };
336 
337 /// mxException for errors closing a file
338 /**
339  * \ingroup exceptions
340  */
341 class filecerr : public mxException
342 {
343 public:
344  filecerr( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
345  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
346  const int & line, ///< [in] the line number where the exception was thrown
347  const std::string & expl ///< [in] the explanation for why the exception was thrown
348  ) : mxException(esrc, MXE_FILECERR,MXE_FILECERR_NAME, efile, line, expl)
349  {
350  }
351  filecerr( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
352  const int & en, ///< [in] the value of errno
353  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
354  const int & line, ///< [in] the line number where the exception was thrown
355  const std::string & expl ///< [in] the explanation for why the exception was thrown
356  ) : mxException(esrc, MXE_FILECERR,MXE_FILECERR_NAME, en, efile, line, expl)
357  {
358  }
359 };
360 
361 /// mxException for errors returned by a library call
362 /**
363  * \ingroup exceptions
364  */
365 class liberr : public mxException
366 {
367 public:
368  liberr( const std::string & esrc, ///< [in] the source of the exception, typically the class and function
369  const std::string & efile, ///< [in] the source file in which the exception occurred, normally __FILE__
370  const int & line, ///< [in] the line number where the exception was thrown
371  const std::string & expl ///< [in] the explanation for why the exception was thrown
372  ) : mxException(esrc, MXE_LIBERR,MXE_LIBERR_NAME, efile, line, expl)
373  {
374  }
375 };
376 
377 /// Throw an exception. This macro takes care of the file and line.
378 /** \ingroup exceptions
379  */
380 #define mxThrowException( extype, src, expl ) throw extype(src, __FILE__, __LINE__, expl);
381 
382 #define mxThrowExceptionErrno( extype, en, src, expl ) throw extype(src, en, __FILE__, __LINE__, expl);
383 
384 } //err
385 } //namespace mx
386 
387 #endif //mxException_hpp
mxException for an allocation error
allocerr(const std::string &esrc, const std::string &efile, const int &line, const std::string &expl)
mxException for errors closing a file
filecerr(const std::string &esrc, const int &en, const std::string &efile, const int &line, const std::string &expl)
filecerr(const std::string &esrc, const std::string &efile, const int &line, const std::string &expl)
mxException for errors on opening a file
fileoerr(const std::string &esrc, const std::string &efile, const int &line, const std::string &expl)
fileoerr(const std::string &esrc, const int &en, const std::string &efile, const int &line, const std::string &expl)
mxException for errors reading from a file
filererr(const std::string &esrc, const std::string &efile, const int &line, const std::string &expl)
filererr(const std::string &esrc, const int &en, const std::string &efile, const int &line, const std::string &expl)
mxException for errors writing to a file
filewerr(const std::string &esrc, const std::string &efile, const int &line, const std::string &expl)
filewerr(const std::string &esrc, const int &en, const std::string &efile, const int &line, const std::string &expl)
mxException for invalid arguments
invalidarg(const std::string &esrc, const std::string &efile, const int &line, const std::string &expl)
mxException for invalid config settings
invalidconfig(const std::string &esrc, const std::string &efile, const int &line, const std::string &expl)
mxException for errors returned by a library call
liberr(const std::string &esrc, const std::string &efile, const int &line, const std::string &expl)
The mxlib exception class.
Definition: mxException.hpp:45
virtual const char * what() const noexcept
Return the details of the exception as a single string.
std::string m_file
The source file where the exception originated.
Definition: mxException.hpp:64
std::string m_source
The source of the exception, such as stdlib or cfitisio or the function name.
Definition: mxException.hpp:52
mxException(const std::string &esrc, const int &ec, const std::string &emnem, const int &en, const std::string &efile, const int &line, const std::string &expl)
Construct and fill in each of the values, including errno.
Definition: mxException.hpp:99
mxException(const mxException &e) noexcept
Copy constructor.
Definition: mxException.hpp:81
int m_line
The line number of the file where the exception originated.
Definition: mxException.hpp:67
std::string m_codeName
The name of the error code.
Definition: mxException.hpp:58
char m_whatstr[4096]
Contains the what() string.
Definition: mxException.hpp:49
mxException(const std::string &esrc, const int &ec, const std::string &emnem, const std::string &efile, const int &line, const std::string &expl)
Construct and fill in each of the values, except errno.
Definition: mxException.hpp:87
virtual ~mxException()
Destructor.
int m_errno
The errno error code (only used if non-zero)
Definition: mxException.hpp:61
std::string m_explanation
The long explanation of the error.
Definition: mxException.hpp:70
int m_code
The mxlib error code.
Definition: mxException.hpp:55
mxException & operator=(const mxException &e) noexcept
Assignment operator.
virtual void build_what()
Build the what string.
mxException() noexcept
Default constructor.
Definition: mxException.hpp:75
mxException for not implemented features
notimpl(const std::string &esrc, const std::string &efile, const int &line, const std::string &expl)
mxException for parameters which aren't set
paramnotset(const std::string &esrc, const std::string &efile, const int &line, const std::string &expl)
mxException for a size error
sizeerr(const std::string &esrc, const std::string &efile, const int &line, const std::string &expl)
std::string errno_CodeToName(int ec)
Return the macro name and a message for a standard errno code.
Definition: mxError.cpp:132
Declares and defines the mxlib error reporting system.
The mxlib c++ namespace.
Definition: mxError.hpp:107