Skip to content

Commit 518f018

Browse files
committed
Refactor Traceable Exception
1 parent 4e701d8 commit 518f018

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#ifndef YSTDLIB_ERROR_HANDLING_TRACEABLEEXCEPTION_HPP
2+
#define YSTDLIB_ERROR_HANDLING_TRACEABLEEXCEPTION_HPP
3+
4+
#include <exception>
5+
#include <source_location>
6+
#include <system_error>
7+
8+
namespace ystdlib::error_handling {
9+
/**
10+
* An exception class that is thrown with an `std::error_code`.
11+
*
12+
* This class extends `std::exception` and can be thrown with an `std::error_code` argument. It also
13+
* provides additional information to aid in debugging by storing details in `std::source_location`,
14+
* including the function name, file name, and line number of the throwing location.
15+
*
16+
* @see std::source_location::file_name()
17+
* @see std::source_location::function_name()
18+
* @see std::source_location::line()
19+
*/
20+
class TraceableException : public std::exception, public std::source_location {
21+
public:
22+
// Constructor
23+
TraceableException(
24+
std::error_code error_code,
25+
std::source_location const& location = std::source_location::current()
26+
)
27+
: std::source_location{location},
28+
m_error_code(error_code) {
29+
m_what = std::string{function_name()} + " operation failed.";
30+
}
31+
32+
// Methods
33+
[[nodiscard]] auto error_code() const -> std::error_code { return m_error_code; }
34+
35+
#ifdef SOURCE_PATH_SIZE
36+
[[nodiscard]] auto file_name() const -> char const* {
37+
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
38+
return std::source_location::file_name() + SOURCE_PATH_SIZE;
39+
}
40+
#endif
41+
42+
// Methods implementing std::exception
43+
[[nodiscard]] auto what() const noexcept -> char const* override { return m_what.c_str(); }
44+
45+
private:
46+
// Variables
47+
std::error_code m_error_code;
48+
std::string m_what;
49+
};
50+
51+
} // namespace ystdlib::error_handling
52+
53+
/**
54+
* The macro to define a `TraceableException` class with the given class name T.
55+
*/
56+
// NOLINTBEGIN(bugprone-macro-parentheses, cppcoreguidelines-macro-usage)
57+
#define YSTDLIB_ERROR_HANDLING_DEFINE_TRACEABLE_EXCEPTION(T) \
58+
class T : public ystdlib::error_handling::TraceableException { \
59+
using ystdlib::error_handling::TraceableException::TraceableException; \
60+
}
61+
// NOLINTEND(bugprone-macro-parentheses, cppcoreguidelines-macro-usage)
62+
63+
#endif // YSTDLIB_ERROR_HANDLING_TRACEABLEEXCEPTION_HPP

0 commit comments

Comments
 (0)