From a95885880fa7c49e125981e3c1ac656a0a6c8ded Mon Sep 17 00:00:00 2001
From: Patrick Wuttke
Date: Sat, 30 Aug 2025 00:30:47 +0200
Subject: [PATCH] Added formatter for exceptions.
---
source/mijin/util/exception.hpp | 74 +++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/source/mijin/util/exception.hpp b/source/mijin/util/exception.hpp
index 7ad87e3..1f0b776 100644
--- a/source/mijin/util/exception.hpp
+++ b/source/mijin/util/exception.hpp
@@ -4,8 +4,11 @@
#ifndef MIJIN_UTIL_EXCEPTION_HPP_INCLUDED
#define MIJIN_UTIL_EXCEPTION_HPP_INCLUDED 1
+#include
#include
+#include
+#include "../detect.hpp"
#include "../debug/stacktrace.hpp"
namespace mijin
@@ -73,5 +76,76 @@ void walkExceptionCause(const std::exception_ptr& cause, TFunc func)
}
}
}
+
+template
+void walkException(const std::exception& exc, TFunc func)
+{
+ func(exc);
+}
+
+template
+void walkException(const mijin::Exception& exc, TFunc func)
+{
+ func(exc);
+ walkExceptionCause(exc.getCause(), func);
+}
} // namespace mijin
+
+template
+struct std::formatter
+{
+ using char_t = TChar;
+
+ template
+ constexpr TContext::iterator parse(TContext& ctx)
+ {
+ auto it = ctx.begin();
+ auto end = ctx.end();
+
+ if (it != end && *it != MIJIN_SMART_QUOTE(char_t, '}'))
+ {
+ throw std::format_error("invalid format");
+ }
+
+ return it;
+ }
+
+ template
+ TContext::iterator format(const mijin::Exception& exception, TContext& ctx) const
+ {
+ using namespace std::literals;
+
+ auto it = ctx.out();
+ bool first = true;
+ mijin::walkException(exception, [&](const T& exc)
+ {
+ if constexpr (!std::is_same_v)
+ {
+ if (!first) {
+ it = std::ranges::copy(MIJIN_SMART_QUOTE(char_t, "\nCaused by:\n"sv), it).out;
+ }
+ first = false;
+#if MIJIN_RTTI
+ it = std::ranges::copy(std::basic_string_view(typeid(exc).name()), it).out;
+ it = std::ranges::copy(MIJIN_SMART_QUOTE(char_t, ": "sv), it).out;
+#endif
+ it = std::ranges::copy(std::basic_string_view(exc.what()), it).out;
+ if constexpr (std::is_same_v)
+ {
+ if (const mijin::Result& trace = exc.getStacktrace(); trace.isSuccess())
+ {
+ *it = MIJIN_SMART_QUOTE(char_t, '\n');
+ ++it;
+ it = std::format_to(it, MIJIN_SMART_QUOTE(char_t, "{}"), trace.getValue());
+ }
+ }
+ }
+ else
+ {
+ it = std::ranges::copy(MIJIN_SMART_QUOTE(char_t, ""sv), it).out;
+ }
+ });
+ return it;
+ }
+};
#endif // MIJIN_UTIL_EXCEPTION_HPP_INCLUDED