diff options
author | svkrasnov <svkrasnov@yandex-team.ru> | 2022-03-23 14:49:38 +0300 |
---|---|---|
committer | svkrasnov <svkrasnov@yandex-team.ru> | 2022-03-23 14:49:38 +0300 |
commit | 0e6dafca9899ab0baf5ec5874ab205f0d8fa7f11 (patch) | |
tree | 5ef144b410bbc505a4dd07a3d1cc830d874bc606 /util/generic/yexception.cpp | |
parent | ea82b3450005272f1a406cf1eac7a245c2e7c1ee (diff) | |
download | ydb-0e6dafca9899ab0baf5ec5874ab205f0d8fa7f11.tar.gz |
Introduce FormatCurrentException() based on TBackTrace::FromCurrentException()
ref:60218909c48b580eebc0b518f039afd46ca51713
Diffstat (limited to 'util/generic/yexception.cpp')
-rw-r--r-- | util/generic/yexception.cpp | 53 |
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; } |