Repository: ClickHouse/ClickHouse
File: src/Common/Exception.cpp (C++)

Code before:
}

Exception::~Exception()
try
{
    if (!logged.load(std::memory_order_relaxed) && isErrorCodeImportant())
    {
        LOG_ERROR(getLogger("ForcedCriticalErrorsLogger"), "{}", getExceptionMessage(*this, /*with_stacktrace=*/ true));
    }
}
catch (...) // NOLINT(bugprone-empty-catch)
{
}

template <class Logger>
static void tryLogCurrentExceptionImpl(Logger logger, const std::string & start_of_message, LogsLevel level)
{
    try
    {
        PreformattedMessage message = getCurrentExceptionMessageAndPattern(true);
        if (start_of_message.empty())
        {
            switch (level)
            {
                case LogsLevel::none: break;
                case LogsLevel::test: LOG_TEST(std::move(logger), message); break;
                case LogsLevel::trace: LOG_TRACE(std::move(logger), message); break;
                case LogsLevel::debug: LOG_DEBUG(std::move(logger), message); break;
                case LogsLevel::information: LOG_INFO(std::move(logger), message); break;
                case LogsLevel::warning: LOG_WARNING(std::move(logger), message); break;
                case LogsLevel::error: LOG_ERROR(std::move(logger), message); break;
                case LogsLevel::fatal: LOG_FATAL(std::move(logger), message); break;
            }
        }
        else
        {
            switch (level)
            {
                case LogsLevel::none: break;
                case LogsLevel::test: LOG_TEST(std::move(logger), "{}: {}", start_of_message, message.text); break;
                case LogsLevel::trace: LOG_TRACE(std::move(logger), "{}: {}", start_of_message, message.text); break;
                case LogsLevel::debug: LOG_DEBUG(std::move(logger), "{}: {}", start_of_message, message.text); break;
                case LogsLevel::information: LOG_INFO(std::move(logger), "{}: {}", start_of_message, message.text); break;
                case LogsLevel::warning: LOG_WARNING(std::move(logger), "{}: {}", start_of_message, message.text); break;
                case LogsLevel::error: LOG_ERROR(std::move(logger), "{}: {}", start_of_message, message.text); break;
                case LogsLevel::fatal: LOG_FATAL(std::move(logger), "{}: {}", start_of_message, message.text); break;
            }
        }
    }
    catch (...) // NOLINT(bugprone-empty-catch)
    {

Review comment (suggestion):
I don't quite understand the point of using `std::move` here. These are macros

Code after:
        || error_code == ErrorCodes::POTENTIALLY_BROKEN_DATA_PART
        || error_code == ErrorCodes::CORRUPTED_DATA;
}

Exception::~Exception()
try
{
    if (!logged.load(std::memory_order_relaxed) && isErrorCodeImportant())
    {
        LOG_ERROR(getLogger("ForcedCriticalErrorsLogger"), "{}", getExceptionMessage(*this, /*with_stacktrace=*/ true));
    }
}
catch (...) // NOLINT(bugprone-empty-catch)
{
}

void tryLogCurrentException(const char * log_name, const std::string & start_of_message, LogsLevel level)
{
    /// Explicitly block MEMORY_LIMIT_EXCEEDED
    LockMemoryExceptionInThread lock_memory_tracker(VariableContext::Global);

    /// getLogger can allocate memory too
    auto logger = getLogger(String{log_name});
    tryLogCurrentExceptionImpl(logger.get(), start_of_message, level);
}

void tryLogCurrentException(Poco::Logger * logger, const std::string & start_of_message, LogsLevel level)
{
    /// Explicitly block MEMORY_LIMIT_EXCEEDED
    LockMemoryExceptionInThread lock_memory_tracker(VariableContext::Global);

    tryLogCurrentExceptionImpl(logger, start_of_message, level);
}

void tryLogCurrentException(LoggerPtr logger, const std::string & start_of_message, LogsLevel level)
{
    tryLogCurrentException(logger.get(), start_of_message, level);
}

void tryLogCurrentException(const AtomicLogger & logger, const std::string & start_of_message, LogsLevel level)
{
    tryLogCurrentException(logger.load(), start_of_message, level);
}

static void getNoSpaceLeftInfoMessage(std::filesystem::path path, String & msg)
{
    path = std::filesystem::absolute(path);
    /// It's possible to get ENOSPC for non existent file (e.g. if there are no free inodes and creat() fails)
    /// So try to get info for existent parent directory.
    while (!std::filesystem::exists(path) && path.has_relative_path())
        path = path.parent_path();