yexception.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "bt_exception.h"
  2. #include "yexception.h"
  3. #include <util/system/backtrace.h>
  4. #include <util/system/type_name.h>
  5. #include <cxxabi.h>
  6. #include <stdexcept>
  7. #include <cstdio>
  8. TString FormatExc(const std::exception& exception) {
  9. return TString::Join(TStringBuf("("), TypeName(exception), TStringBuf(") "), exception.what());
  10. }
  11. TString CurrentExceptionMessage() {
  12. auto exceptionPtr = std::current_exception();
  13. if (exceptionPtr) {
  14. try {
  15. std::rethrow_exception(exceptionPtr);
  16. } catch (const yexception& e) {
  17. const TBackTrace* bt = e.BackTrace();
  18. if (bt) {
  19. return TString::Join(bt->PrintToString(), TStringBuf("\n"), FormatExc(e));
  20. }
  21. return FormatExc(e);
  22. } catch (const std::exception& e) {
  23. return FormatExc(e);
  24. } catch (...) {
  25. }
  26. return "unknown error";
  27. }
  28. return "(NO EXCEPTION)";
  29. }
  30. bool UncaughtException() noexcept {
  31. return std::uncaught_exceptions() > 0;
  32. }
  33. std::string CurrentExceptionTypeName() {
  34. #if defined(_linux_) || defined(_darwin_)
  35. std::type_info* currentExceptionTypePtr = abi::__cxa_current_exception_type();
  36. if (currentExceptionTypePtr) {
  37. return TypeName(*currentExceptionTypePtr);
  38. }
  39. #endif
  40. //There is no abi::__cxa_current_exception_type() on Windows.
  41. //Emulated it with rethrow - catch construction.
  42. std::exception_ptr currentException = std::current_exception();
  43. Y_ASSERT(currentException != nullptr);
  44. try {
  45. std::rethrow_exception(currentException);
  46. } catch (const std::exception& e) {
  47. return TypeName(typeid(e));
  48. } catch (...) {
  49. return "unknown type";
  50. }
  51. }
  52. void TSystemError::Init() {
  53. yexception& exc = *this;
  54. exc << TStringBuf("(");
  55. exc << TStringBuf(LastSystemErrorText(Status_));
  56. exc << TStringBuf(") ");
  57. }
  58. NPrivateException::yexception::yexception() {
  59. ZeroTerminate();
  60. }
  61. TStringBuf NPrivateException::yexception::AsStrBuf() const {
  62. if (Buf_.Left()) {
  63. return TStringBuf(Buf_.Data(), Buf_.Filled());
  64. }
  65. return TStringBuf(Buf_.Data(), Buf_.Filled() - 1);
  66. }
  67. void NPrivateException::yexception::ZeroTerminate() noexcept {
  68. char* end = (char*)Buf_.Current();
  69. if (!Buf_.Left()) {
  70. --end;
  71. }
  72. *end = 0;
  73. }
  74. const char* NPrivateException::yexception::what() const noexcept {
  75. return Buf_.Data();
  76. }
  77. const TBackTrace* NPrivateException::yexception::BackTrace() const noexcept {
  78. return nullptr;
  79. }
  80. void fputs(const std::exception& e, FILE* f) {
  81. char message[256];
  82. size_t len = Min(sizeof(message) - 2, strlcpy(message, e.what(), sizeof(message) - 1));
  83. message[len++] = '\n';
  84. message[len] = 0;
  85. fputs(message, f);
  86. }
  87. void ::NPrivate::ThrowYException(const ::NPrivate::TSimpleExceptionMessage& sm) {
  88. throw sm.Location + yexception() << sm.Message;
  89. }
  90. void ::NPrivate::ThrowYExceptionWithBacktrace(const ::NPrivate::TSimpleExceptionMessage& sm) {
  91. throw sm.Location + TWithBackTrace<yexception>() << sm.Message;
  92. }