aboutsummaryrefslogtreecommitdiffstats
path: root/util/generic/yexception.cpp
diff options
context:
space:
mode:
authorsvkrasnov <svkrasnov@yandex-team.ru>2022-03-23 14:49:38 +0300
committersvkrasnov <svkrasnov@yandex-team.ru>2022-03-23 14:49:38 +0300
commit0e6dafca9899ab0baf5ec5874ab205f0d8fa7f11 (patch)
tree5ef144b410bbc505a4dd07a3d1cc830d874bc606 /util/generic/yexception.cpp
parentea82b3450005272f1a406cf1eac7a245c2e7c1ee (diff)
downloadydb-0e6dafca9899ab0baf5ec5874ab205f0d8fa7f11.tar.gz
Introduce FormatCurrentException() based on TBackTrace::FromCurrentException()
ref:60218909c48b580eebc0b518f039afd46ca51713
Diffstat (limited to 'util/generic/yexception.cpp')
-rw-r--r--util/generic/yexception.cpp53
1 files changed, 52 insertions, 1 deletions
diff --git a/util/generic/yexception.cpp b/util/generic/yexception.cpp
index 26c75b5f51..ee6d6ebe17 100644
--- a/util/generic/yexception.cpp
+++ b/util/generic/yexception.cpp
@@ -10,8 +10,14 @@
#include <cstdio>
+static void FormatExceptionTo(IOutputStream& out, const std::exception& exception) {
+ out << "(" << TypeName(exception) << ") " << exception.what();
+}
+
TString FormatExc(const std::exception& exception) {
- return TString::Join(TStringBuf("("), TypeName(exception), TStringBuf(") "), exception.what());
+ TStringStream out;
+ FormatExceptionTo(out, exception);
+ return out.Str();
}
TString CurrentExceptionMessage() {
@@ -38,6 +44,51 @@ TString CurrentExceptionMessage() {
return "(NO EXCEPTION)";
}
+Y_DECLARE_UNUSED static void FormatBackTraceTo(IOutputStream& out, const TBackTrace& backtrace) {
+ if (backtrace.size() == 0) {
+ out << "backtrace is empty";
+ return;
+ }
+ try {
+ backtrace.PrintTo(out);
+ } catch (const std::exception& e) {
+ out << "Failed to print backtrace: ";
+ FormatExceptionTo(out, e);
+ }
+}
+
+void FormatCurrentExceptionTo(IOutputStream& out) {
+ auto exceptionPtr = std::current_exception();
+ /*
+ * The lack of current exception indicates a logical bug in the client code.
+ * Do not make any attempts to workaround it, just panic and abort.
+ */
+ Y_VERIFY(exceptionPtr != nullptr, "there is no current exception");
+#ifdef _YNDX_LIBUNWIND_ENABLE_EXCEPTION_BACKTRACE
+ TBackTrace backtrace = TBackTrace::FromCurrentException();
+#endif
+ try {
+ std::rethrow_exception(exceptionPtr);
+ } catch (const std::exception& e) {
+ out << "Caught:\n";
+ FormatExceptionTo(out, e);
+#ifdef _YNDX_LIBUNWIND_ENABLE_EXCEPTION_BACKTRACE
+ out << "\n\n";
+ FormatBackTraceTo(out, backtrace);
+#endif
+ return;
+ } catch (...) {
+ out << "unknown error";
+ return;
+ }
+}
+
+TString FormatCurrentException() {
+ TStringStream out;
+ FormatCurrentExceptionTo(out);
+ return out.Str();
+}
+
bool UncaughtException() noexcept {
return std::uncaught_exceptions() > 0;
}