#ifndef __UT_EXCEPTION_HPP__ #define __UT_EXCEPTION_HPP__ #include #define UT_MAX_TRACE_ADDR_NUMBER 64 namespace unitree { namespace common { class Exception : public std::exception { public: Exception() throw() : Exception(UT_ERR_UNKNOWN, UT_DESC_ERR(UT_ERR_UNKNOWN)) {} Exception(int32_t code, const std::string& message) throw() : mCode(code), mMessage(message), mLine(0) {} virtual ~Exception() {} int32_t GetCode() const { return mCode; } const std::string& GetMessage() const { return mMessage; } virtual const char* what() const noexcept { return mMessage.c_str(); } virtual std::string GetClassName() const { return "Exception"; } void Init(const char* file, const char* func, int32_t line) { mFile = file; mFunc = func; mLine = line; } std::string ToString() const { std::ostringstream os; AddDetail(os); return os.str(); } std::string StackTrace() const { std::ostringstream os; AddDetail(os); AddBackTrace(os); return os.str(); } protected: void AddDetail(std::ostringstream& os) const { os << "Catch " << GetClassName() << " code:" << mCode << ", message:" << mMessage << std::endl; if (!mFile.empty() && !mFunc.empty() && mLine > 0) { os << " at __FILE__:" << mFile << ", __LINE__:" << mLine << ", __FUNCTION__:" << mFunc << std::endl; } } void AddBackTrace(std::ostringstream& os) const { os << "Stack:" << std::endl; void* addr[UT_MAX_TRACE_ADDR_NUMBER]; int32_t number = backtrace(addr, UT_MAX_TRACE_ADDR_NUMBER); char **info = backtrace_symbols(addr, number); if(info == NULL) { return; } for(int32_t i=0; i