]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/leaf/examples/error_log.cpp
1 // Copyright (c) 2018-2020 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 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.
12 // This example is similar to error_trace, except the path the error takes is not captured,
15 #include <boost/leaf/on_error.hpp>
16 #include <boost/leaf/handle_errors.hpp>
17 #include <boost/leaf/result.hpp>
21 #define ENABLE_ERROR_LOG 1
23 namespace leaf
= boost::leaf
;
25 // The error log is activated only if an error-handling scope provides a handler for e_error_log.
32 friend std::ostream
& operator<<( std::ostream
& os
, rec
const & x
)
34 return os
<< x
.file
<< '(' << x
.line
<< ')';
40 std::cerr
<< "Error! Log:" << std::endl
;
43 // Our e_error_log instance is stateless, used only as a target to operator<<.
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 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__}; } )
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.
59 int const failure_percent
= 25;
61 leaf::result
<void> f1()
64 if( (std::rand()%100) > failure_percent
)
67 return leaf::new_error();
70 leaf::result
<void> f2()
73 if( (std::rand()%100) > failure_percent
)
76 return leaf::new_error();
79 leaf::result
<void> f3()
82 if( (std::rand()%100) > failure_percent
)
85 return leaf::new_error();
88 leaf::result
<void> f4()
91 if( (std::rand()%100) > failure_percent
)
94 return leaf::new_error();
97 leaf::result
<void> f5()
100 if( (std::rand()%100) > failure_percent
)
103 return leaf::new_error();
108 for( int i
=0; i
!=10; ++i
)
109 leaf::try_handle_all(
110 [&]() -> leaf::result
<void>
112 std::cout
<< "Run # " << i
<< ": ";
113 BOOST_LEAF_CHECK(f5());
114 std::cout
<< "Success!" << std::endl
;
117 #if ENABLE_ERROR_LOG // This single #if enables or disables the printing of the error log.
118 []( e_error_log
const & )
124 std::cerr
<< "Error!" << std::endl
;
129 ////////////////////////////////////////
131 #ifdef BOOST_LEAF_NO_EXCEPTIONS
135 BOOST_LEAF_NORETURN
void throw_exception( std::exception
const & e
)
137 std::cerr
<< "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e
.what();
141 struct source_location
;
142 BOOST_LEAF_NORETURN
void throw_exception( std::exception
const & e
, boost::source_location
const & )