ClickHouse/dbms/src/Common/Exception.cpp

188 lines
3.7 KiB
C++
Raw Normal View History

2012-05-14 20:37:10 +00:00
#include <errno.h>
#include <string.h>
2014-07-21 09:11:20 +00:00
#include <cxxabi.h>
2012-05-14 20:37:10 +00:00
2015-09-29 19:19:54 +00:00
#include <common/logger_useful.h>
2013-11-18 19:18:03 +00:00
2013-06-21 20:34:19 +00:00
#include <DB/IO/WriteHelpers.h>
2012-05-14 20:37:10 +00:00
2015-10-05 01:31:57 +00:00
#include <DB/Common/Exception.h>
2010-03-01 16:59:51 +00:00
namespace DB
{
2011-12-12 06:15:34 +00:00
namespace ErrorCodes
{
extern const int POCO_EXCEPTION;
extern const int STD_EXCEPTION;
extern const int UNKNOWN_EXCEPTION;
extern const int CANNOT_TRUNCATE_FILE;
}
void throwFromErrno(const std::string & s, int code, int e)
2012-05-14 20:37:10 +00:00
{
char buf[128];
throw ErrnoException(s + ", errno: " + toString(e) + ", strerror: " + std::string(strerror_r(e, buf, sizeof(buf))), code, e);
2012-05-14 20:37:10 +00:00
}
inline std::string demangle(const char * const mangled, int & status)
{
const auto demangled_str = abi::__cxa_demangle(mangled, 0, 0, &status);
std::string demangled{demangled_str};
free(demangled_str);
return demangled;
}
void tryLogCurrentException(const char * log_name, const std::string & start_of_message)
{
tryLogCurrentException(&Logger::get(log_name), start_of_message);
}
void tryLogCurrentException(Poco::Logger * logger, const std::string & start_of_message)
2013-11-18 19:18:03 +00:00
{
try
{
LOG_ERROR(logger, start_of_message << (start_of_message.empty() ? "" : ": ") << getCurrentExceptionMessage(true));
}
catch (...)
{
}
}
std::string getCurrentExceptionMessage(bool with_stacktrace)
{
std::stringstream stream;
2013-11-18 19:18:03 +00:00
try
{
throw;
}
catch (const Exception & e)
{
try
{
stream << "Code: " << e.code() << ", e.displayText() = " << e.displayText() << ", e.what() = " << e.what();
if (with_stacktrace)
stream << ", Stack trace:\n\n" << e.getStackTrace().toString();
2013-11-18 19:18:03 +00:00
}
catch (...) {}
}
catch (const Poco::Exception & e)
{
try
{
stream << "Poco::Exception. Code: " << ErrorCodes::POCO_EXCEPTION << ", e.code() = " << e.code()
<< ", e.displayText() = " << e.displayText() << ", e.what() = " << e.what();
2013-11-18 19:18:03 +00:00
}
catch (...) {}
}
catch (const std::exception & e)
{
try
{
int status = 0;
auto name = demangle(typeid(e).name(), status);
2014-07-21 09:11:20 +00:00
if (status)
name += " (demangling status: " + toString(status) + ")";
stream << "std::exception. Code: " << ErrorCodes::STD_EXCEPTION << ", type: " << name << ", e.what() = " << e.what();
2013-11-18 19:18:03 +00:00
}
catch (...) {}
}
catch (...)
{
try
{
int status = 0;
auto name = demangle(abi::__cxa_current_exception_type()->name(), status);
if (status)
name += " (demangling status: " + toString(status) + ")";
stream << "Unknown exception. Code: " << ErrorCodes::UNKNOWN_EXCEPTION << ", type: " << name;
2013-11-18 19:18:03 +00:00
}
catch (...) {}
}
return stream.str();
2013-11-18 19:18:03 +00:00
}
std::unique_ptr<Poco::Exception> convertCurrentException()
2015-10-05 05:40:27 +00:00
{
try
{
throw;
}
catch (const Exception & e)
{
return std::unique_ptr<Poco::Exception>{ e.clone() };
2015-10-05 05:40:27 +00:00
}
catch (const Poco::Exception & e)
{
return std::unique_ptr<Poco::Exception>{ e.clone() };
2015-10-05 05:40:27 +00:00
}
catch (const std::exception & e)
{
return std::make_unique<Exception>(e.what(), ErrorCodes::STD_EXCEPTION);
2015-10-05 05:40:27 +00:00
}
catch (...)
{
return std::make_unique<Exception>("Unknown exception", ErrorCodes::UNKNOWN_EXCEPTION);
2015-10-05 05:40:27 +00:00
}
}
void rethrowFirstException(Exceptions & exceptions)
{
for (size_t i = 0, size = exceptions.size(); i < size; ++i)
if (exceptions[i])
2015-10-05 05:40:27 +00:00
std::rethrow_exception(exceptions[i]);
}
void tryLogException(std::exception_ptr e, const char * log_name, const std::string & start_of_message)
{
try
{
std::rethrow_exception(e);
}
catch (...)
{
tryLogCurrentException(log_name, start_of_message);
}
}
void tryLogException(std::exception_ptr e, Poco::Logger * logger, const std::string & start_of_message)
{
try
{
std::rethrow_exception(e);
}
catch (...)
{
tryLogCurrentException(logger, start_of_message);
}
}
std::string getExceptionMessage(std::exception_ptr e, bool with_stacktrace)
{
try
{
std::rethrow_exception(e);
}
catch (...)
{
return getCurrentExceptionMessage(with_stacktrace);
}
}
2010-03-01 16:59:51 +00:00
}