]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/leaf/example/error_log.cpp
1 // Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc.
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)
6 // This program demonstrates the use of leaf::on_error to print the path an
7 // error takes 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. Otherwise none of the
10 // error log machinery will be invoked by LEAF.
12 // This example is similar to error_trace, except the path the error takes is
13 // not captured, only printed.
15 #include <boost/leaf.hpp>
19 #define ENABLE_ERROR_LOG 1
21 namespace leaf
= boost::leaf
;
23 // The error log is activated only if an error handling scope provides a handler
31 friend std::ostream
& operator<<( std::ostream
& os
, rec
const & x
)
33 return os
<< x
.file
<< '(' << x
.line
<< ')';
39 std::cerr
<< "Error! Log:" << std::endl
;
42 // Our e_error_log instance is stateless, used only as a target to
45 friend std::ostream
& operator<<( e_error_log
const &, T
const & x
)
47 return std::cerr
<< x
<< std::endl
;
51 // The ERROR_LOG macro is designed for use in functions that detect or forward
52 // errors up the call stack. If an error occurs, and if an error handling scope
53 // provides a handler for e_error_log, the supplied lambda is executed as the
55 #define ERROR_LOG auto _log = leaf::on_error( []( e_error_log & log ) { log << e_error_log::rec{__FILE__, __LINE__}; } )
57 // Each function in the sequence below calls the previous function, and each
58 // function has failure_percent chance of failing. If a failure occurs, the
59 // ERROR_LOG macro will cause the path the error takes to be printed.
60 int const failure_percent
= 25;
62 leaf::result
<void> f1()
65 if( (std::rand()%100) > failure_percent
)
68 return leaf::new_error();
71 leaf::result
<void> f2()
74 if( (std::rand()%100) > failure_percent
)
77 return leaf::new_error();
80 leaf::result
<void> f3()
83 if( (std::rand()%100) > failure_percent
)
86 return leaf::new_error();
89 leaf::result
<void> f4()
92 if( (std::rand()%100) > failure_percent
)
95 return leaf::new_error();
98 leaf::result
<void> f5()
101 if( (std::rand()%100) > failure_percent
)
104 return leaf::new_error();
109 for( int i
=0; i
!=10; ++i
)
110 leaf::try_handle_all(
111 [&]() -> leaf::result
<void>
113 std::cout
<< "Run # " << i
<< ": ";
114 BOOST_LEAF_CHECK(f5());
115 std::cout
<< "Success!" << std::endl
;
118 #if ENABLE_ERROR_LOG // This single #if enables or disables the printing of the error log.
119 []( e_error_log
const & )
125 std::cerr
<< "Error!" << std::endl
;
130 ////////////////////////////////////////
132 #ifdef BOOST_LEAF_NO_EXCEPTIONS
136 BOOST_LEAF_NORETURN
void throw_exception( std::exception
const & e
)
138 std::cerr
<< "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e
.what();
142 struct source_location
;
143 BOOST_LEAF_NORETURN
void throw_exception( std::exception
const & e
, boost::source_location
const & )