16#include <source_location>
59 template<
typename ... Args>
60 Exception(std::source_location location, std::format_string<Args ...> message, Args && ... args)
61 :
std::runtime_error(
std::format(message,
std::forward<Args>(args)...))
62 , _location {
std::move(location) }
71 : std::runtime_error(message)
76 uint32_t
line() const noexcept {
return _location.line(); }
78 char const *
filename() const noexcept {
return _filename(_location.file_name(), _location.file_name() ==
nullptr ? 0 : std::strlen(_location.file_name())); }
80 char const *
function() const noexcept {
return _location.function_name(); }
92 template<
typename ... Args>
93 [[noreturn]]
static void throwNested(std::source_location location, std::format_string<Args ...> message, Args && ... args)
94 { std::throw_with_nested(
Exception(std::move(location), message, std::forward<Args>(args)...)); }
111 static std::vector<std::string>
exceptionStackToString(
Exception const & e, std::size_t initialIndentLevel = 0, std::size_t indentSize = 2,
bool addSourceLocation =
true);
125 std::string
const & loggerName =
"", std::size_t initialIndentLevel = 0,
126 std::string
const & logPattern = noFileLogPattern,
127 std::string
const & currentLogPattern = defaultLogPattern);
138 spdlog::level::level_enum lvl = spdlog::level::err,
139 std::size_t initialIndentLevel = 0,
140 std::string
const & logPattern = noFileLogPattern,
141 std::string
const & currentLogPattern = defaultLogPattern);
144 static constexpr char const * _filename(
char const *
const path, std::size_t
const length)
noexcept
146 if (path ==
nullptr || length == 0 || path[0] ==
'\0')
149 auto file = path + length;
150 while (*file !=
'/' && file != path)
160 std::source_location
const _location;
173 static_assert(!(std::is_same_v<std::decay_t<T>,
char*> ||
174 std::is_array_v<std::remove_reference_t<T>>),
175 "B_ASSERT: First argument appears to be a string literal or array");
177 static_assert(std::is_convertible_v<T, bool>,
178 "B_ASSERT: First argument must be convertible to bool.");
180 return static_cast<bool>(std::forward<T>(expr));
201template<
typename F,
typename ... Args>
202requires std::invocable<F, Args...>
203auto safeInvoke(std::shared_ptr<spdlog::logger> logger, F && f, Args && ... args)
noexcept
205 using Result = std::invoke_result_t<F, Args...>;
209 if constexpr (std::is_void_v<Result>)
210 std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
212 return std::optional<Result>{ std::invoke(std::forward<F>(f), std::forward<Args>(args)...) };
216 catch (std::exception
const & e)
217 {
if (logger !=
nullptr) SPDLOG_LOGGER_ERROR(logger,
"An error occured: {}", e.what()); }
219 {
if (logger !=
nullptr) SPDLOG_LOGGER_ERROR(logger,
"An unknown error occured"); }
221 if constexpr (!std::is_void_v<Result>)
222 return std::optional<Result>{};
227template<
typename F,
typename ... Args>
228requires std::invocable<F, Args...>
229auto safeInvoke(std::string
const & loggerName, F && f, Args && ... args)
noexcept
231 return safeInvoke(spdlog::get(loggerName), std::forward<F>(f), std::forward<Args>(args)...);
237#define CURRENT_SOURCE_LOCATION std::source_location::current()
243#define THROW_NESTED(msg, ...) ::dfx::Utils::Exception::throwNested(CURRENT_SOURCE_LOCATION, msg __VA_OPT__(,) __VA_ARGS__)
246#define THROW(msg, ...) throw ::dfx::Utils::Exception(CURRENT_SOURCE_LOCATION, msg __VA_OPT__(,) __VA_ARGS__)
251#define B_ASSERT(expr, msg, ...) do { if (!::dfx::Utils::__b_assert_expr(expr)) THROW(msg __VA_OPT__(,) __VA_ARGS__); } while (false)
Runtime error that captures a std::source_location.
Definition Exception.hpp:52
char const * filename() const noexcept
Return the base filename from the recorded source location.
Definition Exception.hpp:78
static std::vector< std::string > exceptionStackToString(Exception const &e, std::size_t initialIndentLevel=0, std::size_t indentSize=2, bool addSourceLocation=true)
Convert a nested exception chain to a list of printable lines.
static void printToLogger(Exception const &e, std::shared_ptr< spdlog::logger > logger, spdlog::level::level_enum lvl=spdlog::level::err, std::size_t initialIndentLevel=0, std::string const &logPattern=noFileLogPattern, std::string const ¤tLogPattern=defaultLogPattern)
Log an exception (including nested exceptions) using an explicit logger instance.
uint32_t line() const noexcept
Return the line number recorded in the associated source location.
Definition Exception.hpp:76
static ExceptionStack getExceptionStack(Exception const &e)
Extract a nested exception chain into an ExceptionStack.
Exception(std::source_location location, std::format_string< Args ... > message, Args &&... args)
Construct an exception with a formatted message and a specific source location.
Definition Exception.hpp:60
char const * function() const noexcept
Return the function name recorded in the associated source location.
Definition Exception.hpp:80
static void printToLogger(Exception const &e, spdlog::level::level_enum lvl=spdlog::level::err, std::string const &loggerName="", std::size_t initialIndentLevel=0, std::string const &logPattern=noFileLogPattern, std::string const ¤tLogPattern=defaultLogPattern)
Log an exception (including nested exceptions) using a logger name.
Exception(std::string const &message) noexcept
Construct an exception from an already-formatted message.
Definition Exception.hpp:70
static void throwNested(std::source_location location, std::format_string< Args ... > message, Args &&... args)
Throw an Exception nested within the currently handled exception.
Definition Exception.hpp:93
Definition SystemConfigCommandHandler.hpp:15
constexpr bool __b_assert_expr(T &&expr)
Helper used by B_ASSERT to validate and evaluate the asserted expression.
Definition Exception.hpp:171
auto safeInvoke(std::shared_ptr< spdlog::logger > logger, F &&f, Args &&... args) noexcept
Invoke a callable and catch/log all exceptions.
Definition Exception.hpp:203
std::vector< Exception > ExceptionStack
Convenience alias for a linearized nested exception chain.
Definition Exception.hpp:34