1 /*
2 * This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE
3 */
4 #include "includes.h"
5 
6 #include<iostream>
7 
8 
9 
10 
11 class failing_sink: public spdlog::sinks::sink
12 {
13     void log(const spdlog::details::log_msg& msg) override
14     {
15         throw std::runtime_error("some error happened during log");
16     }
17 
flush()18     void flush()
19     {}
20 };
21 
22 TEST_CASE("default_error_handler", "[errors]]")
23 {
24     prepare_logdir();
25     std::string filename = "logs/simple_log.txt";
26 
27     auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
28     logger->set_pattern("%v");
29     logger->info("Test message {} {}", 1);
30     logger->info("Test message {}", 2);
31     logger->flush();
32 
33     REQUIRE(file_contents(filename) == std::string("Test message 2\n"));
34     REQUIRE(count_lines(filename) == 1);
35 }
36 
37 
38 
39 
40 struct custom_ex
41 {};
42 TEST_CASE("custom_error_handler", "[errors]]")
43 {
44     prepare_logdir();
45     std::string filename = "logs/simple_log.txt";
46     auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
47     logger->flush_on(spdlog::level::info);
48     logger->set_error_handler([=](const std::string& msg)
49     {
50         throw custom_ex();
51     });
52     logger->info("Good message #1");
53     REQUIRE_THROWS_AS(logger->info("Bad format msg {} {}", "xxx"), custom_ex);
54     logger->info("Good message #2");
55     REQUIRE(count_lines(filename) == 2);
56 }
57 
58 TEST_CASE("default_error_handler2", "[errors]]")
59 {
60 
61     auto logger = spdlog::create<failing_sink>("failed_logger");
62     logger->set_error_handler([=](const std::string& msg)
63     {
64         throw custom_ex();
65     });
66     REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex);
67 }
68 
69 TEST_CASE("async_error_handler", "[errors]]")
70 {
71     prepare_logdir();
72     std::string err_msg("log failed with some msg");
73     spdlog::set_async_mode(128);
74     std::string filename = "logs/simple_async_log.txt";
75     {
76         auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
77         logger->set_error_handler([=](const std::string& msg)
78         {
79             std::ofstream ofs("logs/custom_err.txt");
80             if (!ofs) throw std::runtime_error("Failed open logs/custom_err.txt");
81             ofs << err_msg;
82         });
83         logger->info("Good message #1");
84         logger->info("Bad format msg {} {}", "xxx");
85         logger->info("Good message #2");
86         spdlog::drop("logger"); //force logger to drain the queue and shutdown
87         spdlog::set_sync_mode();
88     }
89     REQUIRE(count_lines(filename) == 2);
90     REQUIRE(file_contents("logs/custom_err.txt") == err_msg);
91 }
92 
93 // Make sure async error handler is executed
94 TEST_CASE("async_error_handler2", "[errors]]")
95 {
96     prepare_logdir();
97     std::string err_msg("This is async handler error message");
98     spdlog::set_async_mode(128);
99     {
100         auto logger = spdlog::create<failing_sink>("failed_logger");
101         logger->set_error_handler([=](const std::string& msg)
102         {
103             std::ofstream ofs("logs/custom_err2.txt");
104             if (!ofs) throw std::runtime_error("Failed open logs/custom_err2.txt");
105             ofs << err_msg;
106         });
107         logger->info("Hello failure");
108         spdlog::drop("failed_logger"); //force logger to drain the queue and shutdown
109         spdlog::set_sync_mode();
110     }
111 
112     REQUIRE(file_contents("logs/custom_err2.txt") == err_msg);
113 }
114