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) }
70 explicit Exception(std::string
const & message) noexcept
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)...)); }
116 static std::vector<std::string>
exceptionStackToString(
Exception const & e, std::size_t initialIndentLevel = 0, std::size_t indentSize = 2,
bool addSourceLocation =
true);
130 std::string
const & loggerName =
"", std::size_t initialIndentLevel = 0,
131 std::string
const & logPattern = noFileLogPattern,
132 std::string
const & currentLogPattern = defaultLogPattern);
143 spdlog::level::level_enum lvl = spdlog::level::err,
144 std::size_t initialIndentLevel = 0,
145 std::string
const & logPattern = noFileLogPattern,
146 std::string
const & currentLogPattern = defaultLogPattern);
149 static constexpr char const * _filename(
char const *
const path, std::size_t
const length)
noexcept
151 if (path ==
nullptr || length == 0 || path[0] ==
'\0')
154 auto file = path + length;
155 while (*file !=
'/' && file != path)
165 std::source_location
const _location;
178 static_assert(!(std::is_same_v<std::decay_t<T>,
char*> ||
179 std::is_array_v<std::remove_reference_t<T>>),
180 "DFX_ASSERT: First argument appears to be a string literal or array");
182 static_assert(std::is_convertible_v<T, bool> || std::is_constructible_v<bool, T>,
183 "DFX_ASSERT: First argument must be convertible to bool.");
185 return static_cast<bool>(std::forward<T>(expr));
206template<
typename F,
typename ... Args>
207requires std::invocable<F, Args...>
208auto safeInvoke(std::shared_ptr<spdlog::logger> logger, F && f, Args && ... args)
noexcept
210 using Result = std::invoke_result_t<F, Args...>;
214 if constexpr (std::is_void_v<Result>)
215 std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
217 return std::optional<Result>{ std::invoke(std::forward<F>(f), std::forward<Args>(args)...) };
221 catch (std::exception
const & e)
222 {
if (logger !=
nullptr) SPDLOG_LOGGER_ERROR(logger,
"An error occured: {}", e.what()); }
224 {
if (logger !=
nullptr) SPDLOG_LOGGER_ERROR(logger,
"An unknown error occured"); }
226 if constexpr (!std::is_void_v<Result>)
227 return std::optional<Result>{};
232template<
typename F,
typename ... Args>
233requires std::invocable<F, Args...>
234auto safeInvoke(std::string
const & loggerName, F && f, Args && ... args)
noexcept
236 return safeInvoke(spdlog::get(loggerName), std::forward<F>(f), std::forward<Args>(args)...);
242#define DFX_CURRENT_SOURCE_LOCATION std::source_location::current()
246#define DFX_THROW(msg, ...) \
247 throw ::dfx::Utils::Exception(DFX_CURRENT_SOURCE_LOCATION, msg __VA_OPT__(,) __VA_ARGS__)
253#define DFX_THROW_NESTED(msg, ...) \
254 ::dfx::Utils::Exception::throwNested(DFX_CURRENT_SOURCE_LOCATION, msg __VA_OPT__(,) __VA_ARGS__)
258#define DFX_THROW_VECTOR_NESTED(errors, msg, ...) \
260 try { ::dfx::Utils::Exception::throwNestedVector(errors); } \
261 catch (...) { DFX_THROW_NESTED(msg __VA_OPT__(,) __VA_ARGS__); } \
268#define DFX_ASSERT(expr, msg, ...) \
270 if (!::dfx::Utils::__b_assert_expr(expr)) \
271 DFX_THROW(msg __VA_OPT__(,) __VA_ARGS__); \
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
static void throwNestedVector(std::vector< std::string > const &errors)
Converts a vector of strings into a nested exception chain.
Definition SystemConfigCommandHandler.hpp:15
constexpr bool __b_assert_expr(T &&expr)
Helper used by DFX_ASSERT to validate and evaluate the asserted expression.
Definition Exception.hpp:176
auto safeInvoke(std::shared_ptr< spdlog::logger > logger, F &&f, Args &&... args) noexcept
Invoke a callable and catch/log all exceptions.
Definition Exception.hpp:208
std::vector< Exception > ExceptionStack
Convenience alias for a linearized nested exception chain.
Definition Exception.hpp:34