]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/leaf/examples/error_log.cpp
buildsys: change download over to reef release
[ceph.git] / ceph / src / boost / libs / leaf / examples / error_log.cpp
CommitLineData
20effc67
TL
1// Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
2
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6// This program demonstrates the use of leaf::on_error to print the path an error takes
7// as it bubbles up the call stack. The printing code only runs if:
8// - An error occurs, and
9// - A handler that takes e_error_log argument is present.
10// Otherwise none of the error log machinery will be invoked by LEAF.
11
12// This example is similar to error_trace, except the path the error takes is not captured,
13// only printed.
14
15#include <boost/leaf/on_error.hpp>
16#include <boost/leaf/handle_errors.hpp>
17#include <boost/leaf/result.hpp>
18#include <iostream>
19#include <cstdlib>
20
21#define ENABLE_ERROR_LOG 1
22
23namespace leaf = boost::leaf;
24
25// The error log is activated only if an error-handling scope provides a handler for e_error_log.
26struct e_error_log
27{
28 struct rec
29 {
30 char const * file;
31 int line;
32 friend std::ostream & operator<<( std::ostream & os, rec const & x )
33 {
34 return os << x.file << '(' << x.line << ')';
35 }
36 };
37
38 e_error_log()
39 {
40 std::cerr << "Error! Log:" << std::endl;
41 }
42
43 // Our e_error_log instance is stateless, used only as a target to operator<<.
44 template <class T>
45 friend std::ostream & operator<<( e_error_log const &, T const & x )
46 {
47 return std::cerr << x << std::endl;
48 }
49};
50
51// The ERROR_LOG macro is designed for use in functions that detect or forward errors
52// up the call stack. If an error occurs, and if an error-handling scope provides a handler
53// for e_error_log, the supplied lambda is executed as the error bubbles up.
54#define ERROR_LOG auto _log = leaf::on_error( []( e_error_log & log ) { log << e_error_log::rec{__FILE__, __LINE__}; } )
55
56// Each function in the sequence below calls the previous function, and each function has
57// failure_percent chance of failing. If a failure occurs, the ERROR_LOG macro will cause
58// the path the error takes to be printed.
59int const failure_percent = 25;
60
61leaf::result<void> f1()
62{
63 ERROR_LOG;
64 if( (std::rand()%100) > failure_percent )
65 return { };
66 else
67 return leaf::new_error();
68}
69
70leaf::result<void> f2()
71{
72 ERROR_LOG;
73 if( (std::rand()%100) > failure_percent )
74 return f1();
75 else
76 return leaf::new_error();
77}
78
79leaf::result<void> f3()
80{
81 ERROR_LOG;
82 if( (std::rand()%100) > failure_percent )
83 return f2();
84 else
85 return leaf::new_error();
86}
87
88leaf::result<void> f4()
89{
90 ERROR_LOG;
91 if( (std::rand()%100) > failure_percent )
92 return f3();
93 else
94 return leaf::new_error();
95}
96
97leaf::result<void> f5()
98{
99 ERROR_LOG;
100 if( (std::rand()%100) > failure_percent )
101 return f4();
102 else
103 return leaf::new_error();
104}
105
106int main()
107{
108 for( int i=0; i!=10; ++i )
109 leaf::try_handle_all(
110 [&]() -> leaf::result<void>
111 {
112 std::cout << "Run # " << i << ": ";
113 BOOST_LEAF_CHECK(f5());
114 std::cout << "Success!" << std::endl;
115 return { };
116 },
117#if ENABLE_ERROR_LOG // This single #if enables or disables the printing of the error log.
118 []( e_error_log const & )
119 {
120 },
121#endif
122 []
123 {
124 std::cerr << "Error!" << std::endl;
125 } );
126 return 0;
127}
128
129////////////////////////////////////////
130
131#ifdef BOOST_LEAF_NO_EXCEPTIONS
132
133namespace boost
134{
135 BOOST_LEAF_NORETURN void throw_exception( std::exception const & e )
136 {
137 std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what();
138 std::terminate();
139 }
140
141 struct source_location;
142 BOOST_LEAF_NORETURN void throw_exception( std::exception const & e, boost::source_location const & )
143 {
144 throw_exception(e);
145 }
146}
147
148#endif