Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/common/include/display_device/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ namespace display_device {
/**
* @brief Write out the accumulated output.
*/
virtual ~LogWriter();
virtual ~LogWriter() noexcept;

/**
* @brief Stream value to the buffer.
Expand Down
2 changes: 1 addition & 1 deletion src/common/include/display_device/retry_scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace display_device {
/**
* @brief Executes cleanup logic if scheduler stop was requested.
*/
~SchedulerStopToken();
~SchedulerStopToken() noexcept;

/**
* @brief Request the scheduler to be stopped.
Expand Down
14 changes: 12 additions & 2 deletions src/common/logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

// system includes
#include <chrono>
#include <exception>
#include <iomanip>
#include <iostream>
#include <mutex>
Expand All @@ -29,6 +30,11 @@ namespace display_device {
}
return {};
}

void reportLogWriterException(const std::exception &error) noexcept {
std::cerr << "Exception thrown while writing a log message. Error:\n"
<< error.what() << '\n';
}
} // namespace

Logger &Logger::get() {
Expand Down Expand Up @@ -115,7 +121,11 @@ namespace display_device {
LogWriter::LogWriter(const Logger::LogLevel log_level):
m_log_level {log_level} {}

LogWriter::~LogWriter() {
Logger::get().write(m_log_level, m_buffer.str());
LogWriter::~LogWriter() noexcept {
try {
Logger::get().write(m_log_level, m_buffer.str());
} catch (const std::exception &error) {
reportLogWriterException(error);
}
}
} // namespace display_device
19 changes: 17 additions & 2 deletions src/common/retry_scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,29 @@
// header include
#include "display_device/retry_scheduler.h"

// system includes
#include <exception>
#include <iostream>

namespace display_device {
namespace {
void reportSchedulerStopTokenException(const std::exception &error) noexcept {
std::cerr << "Exception thrown in SchedulerStopToken cleanup. Ignoring. Error:\n"
<< error.what() << '\n';
}
} // namespace

SchedulerStopToken::SchedulerStopToken(std::function<void()> cleanup):
m_cleanup {std::move(cleanup)} {
}

SchedulerStopToken::~SchedulerStopToken() {
SchedulerStopToken::~SchedulerStopToken() noexcept {
if (m_stop_requested && m_cleanup) {
m_cleanup();
try {
m_cleanup();
} catch (const std::exception &error) {
reportSchedulerStopTokenException(error);
}
}
}

Expand Down
22 changes: 22 additions & 0 deletions tests/unit/general/test_logging.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
// system includes
#include <exception>

// local includes
#include "display_device/logging.h"
#include "fixtures/fixtures.h"

namespace {
class LogWriterDestructorTestException final: public std::exception {
public:
[[nodiscard]] const char *what() const noexcept override {
return "Get rekt!";
}
};

// Specialized TEST macro(s) for this test file
#define TEST_S(...) DD_MAKE_TEST(TEST, LoggingTest, __VA_ARGS__)
} // namespace
Expand Down Expand Up @@ -206,3 +216,15 @@ TEST_S(LogMacroDisablesStreamChain) {
EXPECT_EQ(output_logged, true);
EXPECT_EQ(some_function_invoked, true);
}

TEST_S(LogWriterDestructorDoesNotPropagateCallbackExceptions) {
using level = display_device::Logger::LogLevel;
auto &logger {display_device::Logger::get()};

logger.setLogLevel(level::info);
logger.setCustomCallback([](auto, auto) {
throw LogWriterDestructorTestException {};
});

EXPECT_NO_THROW(DD_LOG(info) << "Hello World!");
}
15 changes: 15 additions & 0 deletions tests/unit/general/test_retry_scheduler.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// system includes
#include <exception>
#include <gmock/gmock.h>
#include <stdexcept>

// local includes
#include "display_device/retry_scheduler.h"
Expand All @@ -20,6 +22,13 @@ namespace {
void constMethod() const { /* noop */ }
};

class SchedulerStopTokenTestException final: public std::exception {
public:
[[nodiscard]] const char *what() const noexcept override {
return "Get rekt!";
}
};

// Some threads wake up a little earlier than expected, so we round the lower bound to
// 99% of the expected value to stabilize the tests
int roundTo99(int value) {
Expand Down Expand Up @@ -636,6 +645,12 @@ TEST_F_S(ThreadCleanupInDestructor) {
}

TEST_F_S(SchedulerStopToken, DestructorNoThrow) {
EXPECT_NO_THROW({
display_device::SchedulerStopToken token {[]() {
throw SchedulerStopTokenTestException {};
}};
token.requestStop();
});
EXPECT_NO_THROW({
display_device::SchedulerStopToken token {[]() {
}};
Expand Down
Loading