mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
exception.hpp
Go to the documentation of this file.
1/** \file exception.hpp
2 * \brief The mxlib exception class.
3 * \ingroup error_handling_files
4 *
5 */
6
7//***********************************************************************//
8// Copyright 2025 Jared R. Males (jaredmales@gmail.com)
9//
10// This file is part of mxlib.
11//
12// mxlib is free software: you can redistribute it and/or modify
13// it under the terms of the GNU General Public License as published by
14// the Free Software Foundation, either version 3 of the License, or
15// (at your option) any later version.
16//
17// mxlib is distributed in the hope that it will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20// GNU General Public License for more details.
21//
22// You should have received a copy of the GNU General Public License
23// along with mxlib. If not, see <http://www.gnu.org/licenses/>.
24//***********************************************************************//
25
26#ifndef error_exception_hpp
27#define error_exception_hpp
28
29#include <vector>
30
31#include "error.hpp"
32
33namespace mx
34{
35
36/// Augments an exception with the source file and line
37/**
38 * \tparam baseexcept is the base class exception which takes a string as constructor argument
39 */
40template <class verboseT = verbose::d>
41class exception : public std::exception
42{
43 protected:
44 std::string m_what; ///< The full what message (message + file information).
45
46 error_t m_code{ error_t::exception }; ///< The error_t code
47
48 std::string m_message; ///< The explanatory message
49
50 std::source_location m_location;
51
52 public:
53 /// Constructor with location only.
54 /**
55 */
56 explicit exception( const std::source_location loc = /**< [in] [opt] the location where this was thrown*/
57 std::source_location::current() )
58 : m_location{ loc }
59 {
60 m_what = error_message<verboseT>( m_code, m_location );
61 }
62
63 /// Constructor with message.
64 /**
65 */
66 explicit exception( const std::string &msg, /**< [in] the error description message) */
67 const std::source_location loc = /**< [in] [opt] the location where this was thrown*/
68 std::source_location::current() )
69 : m_message{ msg }, m_location{ loc }
70 {
71 m_what = error_message<verboseT>( m_code, m_message, m_location );
72 }
73
74 /// Constructor with message and cod
75 /**
76 */
77 exception( error_t code, /**< [in] a descriptive error code */
78 const std::string &msg, /**< [in] the error description (what message) */
79 const std::source_location loc = /**< [in] [opt] the location where this was thrown*/
80 std::source_location::current() )
81 : m_code{ code }, m_message{ msg }, m_location{ loc }
82 {
83 m_what = error_message<verboseT>( m_code, m_message, m_location );
84 }
85
86 /// Constructor with code
87 /** The message is filled in using \ref errorMessage.
88 *
89 * The what() message becomes "code_message (code) [file line]".
90 */
91 exception( error_t code, /**< [in] a descriptive error code */
92 const std::source_location loc = /**< [in] [opt] the location where this was thrown*/
93 std::source_location::current() )
94 : m_code{ code }, m_location{ loc }
95 {
96 m_what = error_message<verboseT>( m_code, m_location );
97 }
98
99 /// Get the what string
100 /** \returns the value of m_what.c_str()
101 *
102 */
103 virtual const char *what() const noexcept
104 {
105 return m_what.c_str();
106 }
107
108 /// Get the message
109 /** \returns the value of m_message
110 *
111 */
112 const std::string &message() const
113 {
114 return m_message;
115 }
116
117 /// Get the source file
118 /** \returns the value of m_location.file_name()
119 *
120 */
121 const std::string file_name() const
122 {
123 return m_location.file_name();
124 }
125
126 /// Get the source line
127 /** \returns the value of m_location.line()
128 *
129 */
130 int line() const
131 {
132 return m_location.line();
133 }
134
135 /// Get the error code
136 /** \returns the value of m_code
137 *
138 */
139 error_t code() const
140 {
141 return m_code;
142 }
143};
144
145/// Extract the explanatory string of nested exceptions, placing them in a vector.
146/** If the exception is nested, this recurses to extract the explanatory string of the
147 * next exception it holds.
148 */
149inline
150void unwind_exceptions( std::vector<std::string> &whats, /**< [out] the vector of what messages*/
151 const std::exception &e /**< [in] the exception */
152)
153{
154 whats.push_back( e.what() );
155
156 try
157 {
158 std::rethrow_if_nested( e );
159 }
160 catch( const std::exception &nestedException )
161 {
162 unwind_exceptions( whats, nestedException );
163 }
164 catch( ... )
165 {
166 }
167}
168
169/// Print nested exceptions to stderr, from the earliest to latest
170/** Formats in a ladder
171 *
172*/
173inline
174void print_exceptions( std::vector<std::string> &whats, /**< [out] a vector of what messages*/
175 const std::string &message = /**< [in] [optional] the top message to print */
176 "exception(s) thrown" )
177{
178 std::cerr << message << ":\n";
179 std::cerr << " " << whats.back() << '\n';
180 for( size_t n = 1; n < whats.size(); ++n )
181 {
182 std::cerr << std::string( 2, ' ' ) << std::string( ( n - 1 ) * 4, ' ' ) << "|-->" << whats[whats.size() - 1 - n]
183 << '\n';
184 }
185}
186
187} // namespace mx
188
189#endif // error_exception_hpp
Augments an exception with the source file and line.
Definition exception.hpp:42
exception(const std::source_location loc=std::source_location::current())
Constructor with location only.
Definition exception.hpp:56
std::string m_message
The explanatory message.
Definition exception.hpp:48
const std::string & message() const
Get the message.
error_t code() const
Get the error code.
exception(error_t code, const std::string &msg, const std::source_location loc=std::source_location::current())
Constructor with message and cod.
Definition exception.hpp:77
exception(const std::string &msg, const std::source_location loc=std::source_location::current())
Constructor with message.
Definition exception.hpp:66
exception(error_t code, const std::source_location loc=std::source_location::current())
Constructor with code.
Definition exception.hpp:91
const std::string file_name() const
Get the source file.
int line() const
Get the source line.
virtual const char * what() const noexcept
Get the what string.
std::string m_what
The full what message (message + file information).
Definition exception.hpp:44
error_t m_code
The error_t code.
Definition exception.hpp:46
The mxlib error reporting system.
error_t
The mxlib error codes.
Definition error_t.hpp:26
@ exception
An exception was thrown.
The mxlib c++ namespace.
Definition mxlib.hpp:37
void print_exceptions(std::vector< std::string > &whats, const std::string &message="exception(s) thrown")
Print nested exceptions to stderr, from the earliest to latest.
void unwind_exceptions(std::vector< std::string > &whats, const std::exception &e)
Extract the explanatory string of nested exceptions, placing them in a vector.