test_errors.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. * This content is released under the MIT License as specified in
  3. * https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
  4. */
  5. #include "includes.h"
  6. #include <iostream>
  7. #define SIMPLE_LOG "test_logs/simple_log.txt"
  8. #define SIMPLE_ASYNC_LOG "test_logs/simple_async_log.txt"
  9. class failing_sink : public spdlog::sinks::base_sink<std::mutex> {
  10. protected:
  11. void sink_it_(const spdlog::details::log_msg &) final {
  12. throw std::runtime_error("some error happened during log");
  13. }
  14. void flush_() final { throw std::runtime_error("some error happened during flush"); }
  15. };
  16. struct custom_ex {};
  17. #if !defined(SPDLOG_USE_STD_FORMAT) // std formt doesn't fully support tuntime strings
  18. TEST_CASE("default_error_handler", "[errors]") {
  19. prepare_logdir();
  20. spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG);
  21. auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("test-error", filename, true);
  22. logger->set_pattern("%v");
  23. logger->info(SPDLOG_FMT_RUNTIME("Test message {} {}"), 1);
  24. logger->info("Test message {}", 2);
  25. logger->flush();
  26. using spdlog::details::os::default_eol;
  27. REQUIRE(file_contents(SIMPLE_LOG) == spdlog::fmt_lib::format("Test message 2{}", default_eol));
  28. REQUIRE(count_lines(SIMPLE_LOG) == 1);
  29. }
  30. TEST_CASE("custom_error_handler", "[errors]") {
  31. prepare_logdir();
  32. spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG);
  33. auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
  34. logger->flush_on(spdlog::level::info);
  35. logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
  36. logger->info("Good message #1");
  37. REQUIRE_THROWS_AS(logger->info(SPDLOG_FMT_RUNTIME("Bad format msg {} {}"), "xxx"), custom_ex);
  38. logger->info("Good message #2");
  39. require_message_count(SIMPLE_LOG, 2);
  40. }
  41. #endif
  42. TEST_CASE("default_error_handler2", "[errors]") {
  43. spdlog::drop_all();
  44. auto logger = spdlog::create<failing_sink>("failed_logger");
  45. logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
  46. REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex);
  47. }
  48. TEST_CASE("flush_error_handler", "[errors]") {
  49. spdlog::drop_all();
  50. auto logger = spdlog::create<failing_sink>("failed_logger");
  51. logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
  52. REQUIRE_THROWS_AS(logger->flush(), custom_ex);
  53. }
  54. #if !defined(SPDLOG_USE_STD_FORMAT)
  55. TEST_CASE("async_error_handler", "[errors]") {
  56. prepare_logdir();
  57. std::string err_msg("log failed with some msg");
  58. spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_ASYNC_LOG);
  59. {
  60. spdlog::init_thread_pool(128, 1);
  61. auto logger =
  62. spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
  63. logger->set_error_handler([=](const std::string &) {
  64. std::ofstream ofs("test_logs/custom_err.txt");
  65. if (!ofs) {
  66. throw std::runtime_error("Failed open test_logs/custom_err.txt");
  67. }
  68. ofs << err_msg;
  69. });
  70. logger->info("Good message #1");
  71. logger->info(SPDLOG_FMT_RUNTIME("Bad format msg {} {}"), "xxx");
  72. logger->info("Good message #2");
  73. spdlog::drop("logger"); // force logger to drain the queue and shutdown
  74. }
  75. spdlog::init_thread_pool(128, 1);
  76. require_message_count(SIMPLE_ASYNC_LOG, 2);
  77. REQUIRE(file_contents("test_logs/custom_err.txt") == err_msg);
  78. }
  79. #endif
  80. // Make sure async error handler is executed
  81. TEST_CASE("async_error_handler2", "[errors]") {
  82. prepare_logdir();
  83. std::string err_msg("This is async handler error message");
  84. {
  85. spdlog::details::os::create_dir(SPDLOG_FILENAME_T("test_logs"));
  86. spdlog::init_thread_pool(128, 1);
  87. auto logger = spdlog::create_async<failing_sink>("failed_logger");
  88. logger->set_error_handler([=](const std::string &) {
  89. std::ofstream ofs("test_logs/custom_err2.txt");
  90. if (!ofs) throw std::runtime_error("Failed open test_logs/custom_err2.txt");
  91. ofs << err_msg;
  92. });
  93. logger->info("Hello failure");
  94. spdlog::drop("failed_logger"); // force logger to drain the queue and shutdown
  95. }
  96. spdlog::init_thread_pool(128, 1);
  97. REQUIRE(file_contents("test_logs/custom_err2.txt") == err_msg);
  98. }