|
| 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