mirror of
https://github.com/boostorg/leaf.git
synced 2026-01-24 05:52:17 +00:00
Renamed augment_id to error_monitor
This commit is contained in:
136
doc/leaf.adoc
136
doc/leaf.adoc
@@ -501,7 +501,7 @@ For example, the error may need to be communicated through uncooperative 3rd-par
|
||||
|
||||
Further, it is sometimes necessary to communicate errors through an interface that does not even use `std::error_code`. An example of this is when an external lower-level library throws an exception, which is unlikely to be able to carry an `error_id`.
|
||||
|
||||
To support this tricky use case, LEAF provides the function <<current_error>>, which returns the error ID returned by the most recent call (from this thread) to <<new_error>>. One possible approach to solving the problem is to use the following logic (implemented by the <<augment_id>> type):
|
||||
To support this tricky use case, LEAF provides the function <<current_error>>, which returns the error ID returned by the most recent call (from this thread) to <<new_error>>. One possible approach to solving the problem is to use the following logic (implemented by the <<error_monitor>> type):
|
||||
|
||||
. Before calling the uncooperative API, call <<current_error>> and cache the returned value.
|
||||
. Call the API, then call `current_error` again:
|
||||
@@ -1360,7 +1360,7 @@ NOTE: The complete program illustrating this technique is available https://gith
|
||||
'''
|
||||
|
||||
[[tutorial-on_error_in_c_callbacks]]
|
||||
=== Using `augment_id` to Report Arbitrary Errors from C-callbacks
|
||||
=== Using `error_monitor` to Report Arbitrary Errors from C-callbacks
|
||||
|
||||
Communicating information pertaining to a failure detected in a C callback is tricky, because C callbacks are limited to a specific static signature, which may not use {CPP} types.
|
||||
|
||||
@@ -1443,13 +1443,13 @@ leaf::result<int> call_lua( lua_State * L )
|
||||
{
|
||||
lua_getfield(L, LUA_GLOBALSINDEX, "call_do_work");
|
||||
|
||||
augment_id augment;
|
||||
error_monitor cur_err;
|
||||
if( int err=lua_pcall(L, 0, 1, 0) ) <1>
|
||||
{
|
||||
auto load = leaf::on_error(e_lua_error_message{lua_tostring(L,1)}); <2>
|
||||
lua_pop(L,1);
|
||||
|
||||
return augment.get_error(e_lua_pcall_error{err}); <3>
|
||||
return cur_err.assigned_error_id().load(e_lua_pcall_error{err}); <3>
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1460,11 +1460,11 @@ leaf::result<int> call_lua( lua_State * L )
|
||||
}
|
||||
----
|
||||
[.text-right]
|
||||
<<result>> | <<on_error>> | <<augment_id>>
|
||||
<<result>> | <<on_error>> | <<error_monitor>>
|
||||
|
||||
<1> Ask the Lua interpreter to call the global Lua function `call_do_work`.
|
||||
<2> `on_error` works as usual.
|
||||
<3> `get_error` will return the `error_id` generated in our Lua callback. This is the same `error_id` the `on_error` uses as well.
|
||||
<3> `load` will return the `error_id` generated in our Lua callback. This is the same `error_id` the `on_error` uses as well.
|
||||
<4> Success! Just return the `int` answer.
|
||||
|
||||
Finally, here is the `main` function which exercises `call_lua`, each time handling any failure:
|
||||
@@ -1769,7 +1769,7 @@ namespace boost { namespace leaf {
|
||||
|
||||
This header defines the `on_error` function, which is used for automatic inclusion of error objects with any error exiting the scope in which it is invoked. See <<tutorial-on_error>> and <<tutorial-classification>>.
|
||||
|
||||
The `augment_id` type is used internally by `on_error` to determine the correct <<error_id>> to associate error objects with.
|
||||
The `error_monitor` type is used internally by `on_error` to determine the correct <<error_id>> to associate error objects with.
|
||||
|
||||
====
|
||||
[source,c++]
|
||||
@@ -1780,23 +1780,22 @@ namespace boost { namespace leaf {
|
||||
template <class... Item>
|
||||
<<unspecified-type>> on_error( Item && ... e ) noexcept;
|
||||
|
||||
class augment_id
|
||||
class error_monitor
|
||||
{
|
||||
public:
|
||||
|
||||
augment_id() noexcept;
|
||||
error_monitor() noexcept;
|
||||
|
||||
error_id check_error() const noexcept;
|
||||
error_id check() const noexcept;
|
||||
|
||||
template <class... E>
|
||||
error_id get_error( E && ... e ) const noexcept;
|
||||
error_id assigned_error_id() const noexcept;
|
||||
};
|
||||
|
||||
} }
|
||||
----
|
||||
|
||||
[.text-right]
|
||||
<<on_error>> | <<augment_id>>
|
||||
<<on_error>> | <<error_monitor>>
|
||||
====
|
||||
|
||||
[[exception.hpp]]
|
||||
@@ -2799,62 +2798,6 @@ TIP: The contents of each Reference section are organized alphabetically.
|
||||
|
||||
'''
|
||||
|
||||
[[augment_id]]
|
||||
=== `augment_id`
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
namespace boost { namespace leaf {
|
||||
|
||||
class augment_id
|
||||
{
|
||||
public:
|
||||
|
||||
augment_id() noexcept;
|
||||
|
||||
error_id check_error() const noexcept;
|
||||
|
||||
template <class... E>
|
||||
error_id get_error( E && ... e ) const noexcept;
|
||||
};
|
||||
|
||||
} }
|
||||
----
|
||||
|
||||
This class helps obtain an <<error_id>> to associate error objects with, when augmenting failures communicated using LEAF through uncooperative APIs that do not use LEAF to report errors (and therefore do not return an `error_id` on error).
|
||||
|
||||
The common usage of this class is as follows:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
error_code compute_value( int * out_value ) noexcept; <1>
|
||||
|
||||
leaf::error<int> augmenter() noexcept
|
||||
{
|
||||
leaf::augment_id augment; <2>
|
||||
|
||||
int val;
|
||||
auto ec = compute_value(&val);
|
||||
|
||||
if( failure(ec) )
|
||||
return augment.get_error(e1, e2, ...); <3>
|
||||
else
|
||||
return val; <4>
|
||||
}
|
||||
----
|
||||
<1> Uncooperative third-party API that does not use LEAF, but results in calling a user callback that does use LEAF. In case our callback reports a failure, we'll augment it with error objects available in the calling scope, even though `compute_value` can not communicate an <<error_id>>.
|
||||
<2> Initialize an `augment_id` object.
|
||||
<3> The call to `compute_value` has failed:
|
||||
- If <<new_error>> was invoked (by the calling thread) after the `augment` object was initialized, `get_error` returns the last `error_id` returned by `new_error`. This would be the case if the failure originates in our callback (invoked internally by `compute_value`).
|
||||
- Else, `get_error` invokes `new_error` and returns that `error_id`.
|
||||
<4> The call was successful, return the computed value.
|
||||
|
||||
The `check_error` function works similarly, but instead of invoking `new_error` it returns a defaul-initialized `error_id`.
|
||||
|
||||
TIP: See <<tutorial-on_error_in_c_callbacks>>.
|
||||
|
||||
'''
|
||||
|
||||
[[catch_]]
|
||||
=== `catch_`
|
||||
|
||||
@@ -3428,6 +3371,61 @@ Effects: ::
|
||||
|
||||
'''
|
||||
|
||||
[[error_monitor]]
|
||||
=== `error_monitor`
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
namespace boost { namespace leaf {
|
||||
|
||||
class error_monitor
|
||||
{
|
||||
public:
|
||||
|
||||
error_monitor() noexcept;
|
||||
|
||||
error_id check() const noexcept;
|
||||
|
||||
error_id assigned_error_id( E && ... e ) const noexcept;
|
||||
};
|
||||
|
||||
} }
|
||||
----
|
||||
|
||||
This class helps obtain an <<error_id>> to associate error objects with, when augmenting failures communicated using LEAF through uncooperative APIs that do not use LEAF to report errors (and therefore do not return an `error_id` on error).
|
||||
|
||||
The common usage of this class is as follows:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
error_code compute_value( int * out_value ) noexcept; <1>
|
||||
|
||||
leaf::error<int> augmenter() noexcept
|
||||
{
|
||||
leaf::error_monitor cur_err; <2>
|
||||
|
||||
int val;
|
||||
auto ec = compute_value(&val);
|
||||
|
||||
if( failure(ec) )
|
||||
return cur_err.assigned_error_id().load(e1, e2, ...); <3>
|
||||
else
|
||||
return val; <4>
|
||||
}
|
||||
----
|
||||
<1> Uncooperative third-party API that does not use LEAF, but results in calling a user callback that does use LEAF. In case our callback reports a failure, we'll augment it with error objects available in the calling scope, even though `compute_value` can not communicate an <<error_id>>.
|
||||
<2> Initialize an `error_monitor` object.
|
||||
<3> The call to `compute_value` has failed:
|
||||
- If <<new_error>> was invoked (by the calling thread) after the `augment` object was initialized, `assigned_error_id` returns the last `error_id` returned by `new_error`. This would be the case if the failure originates in our callback (invoked internally by `compute_value`).
|
||||
- Else, `assigned_error_id` invokes `new_error` and returns that `error_id`.
|
||||
<4> The call was successful, return the computed value.
|
||||
|
||||
The `check` function works similarly, but instead of invoking `new_error` it returns a defaul-initialized `error_id`.
|
||||
|
||||
TIP: See <<tutorial-on_error_in_c_callbacks>>.
|
||||
|
||||
'''
|
||||
|
||||
[[e_api_function]]
|
||||
=== `e_api_function`
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ std::shared_ptr<lua_State> init_lua_state()
|
||||
// If it fails, we'll communicate that failure to our caller.
|
||||
leaf::result<int> call_lua( lua_State * L )
|
||||
{
|
||||
leaf::augment_id augment;
|
||||
leaf::error_monitor cur_err;
|
||||
|
||||
// Ask the Lua interpreter to call the global Lua function call_do_work.
|
||||
lua_getfield( L, LUA_GLOBALSINDEX, "call_do_work" );
|
||||
@@ -86,9 +86,9 @@ leaf::result<int> call_lua( lua_State * L )
|
||||
lua_pop(L,1);
|
||||
|
||||
// We got a Lua error which may be the error we're reporting from do_work, or some other error.
|
||||
// If it is another error, augment.get_error() will return a new leaf::error_id, otherwise
|
||||
// we'll be working with the original value returned by leaf::new_error in do_work.
|
||||
return augment.get_error(e_lua_pcall_error{err});
|
||||
// If it is another error, cur_err.assigned_error_id() will return a new leaf::error_id,
|
||||
// otherwise we'll be working with the original value returned by leaf::new_error in do_work.
|
||||
return cur_err.assigned_error_id().load(e_lua_pcall_error{err});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1867,7 +1867,7 @@ namespace boost { namespace leaf {
|
||||
|
||||
namespace boost { namespace leaf {
|
||||
|
||||
class augment_id
|
||||
class error_monitor
|
||||
{
|
||||
#if !defined(BOOST_LEAF_NO_EXCEPTIONS) && BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
|
||||
int const uncaught_exceptions_;
|
||||
@@ -1876,7 +1876,7 @@ namespace boost { namespace leaf {
|
||||
|
||||
public:
|
||||
|
||||
augment_id() noexcept:
|
||||
error_monitor() noexcept:
|
||||
#if !defined(BOOST_LEAF_NO_EXCEPTIONS) && BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
|
||||
uncaught_exceptions_(std::uncaught_exceptions()),
|
||||
#endif
|
||||
@@ -1912,15 +1912,14 @@ namespace boost { namespace leaf {
|
||||
return leaf_detail::new_id();
|
||||
}
|
||||
|
||||
error_id check_error() const noexcept
|
||||
error_id check() const noexcept
|
||||
{
|
||||
return leaf_detail::make_error_id(check_id());
|
||||
}
|
||||
|
||||
template <class... E>
|
||||
error_id get_error( E && ... e ) const noexcept
|
||||
error_id assigned_error_id() const noexcept
|
||||
{
|
||||
return leaf_detail::make_error_id(get_id()).load(std::forward<E>(e)...);
|
||||
return leaf_detail::make_error_id(get_id());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2051,7 +2050,7 @@ namespace boost { namespace leaf {
|
||||
|
||||
std::tuple<Item...> p_;
|
||||
bool moved_;
|
||||
augment_id id_;
|
||||
error_monitor id_;
|
||||
|
||||
public:
|
||||
|
||||
@@ -2194,7 +2193,7 @@ namespace boost { namespace leaf {
|
||||
inline decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...)) capture_impl(is_result_tag<R, false>, context_ptr && ctx, F && f, A... a)
|
||||
{
|
||||
auto active_context = activate_context(*ctx);
|
||||
augment_id aug;
|
||||
error_monitor cur_err;
|
||||
try
|
||||
{
|
||||
return std::forward<F>(f)(std::forward<A>(a)...);
|
||||
@@ -2210,7 +2209,7 @@ namespace boost { namespace leaf {
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
ctx->captured_id_ = aug.get_error();
|
||||
ctx->captured_id_ = cur_err.assigned_error_id();
|
||||
throw_exception( capturing_exception(std::current_exception(), std::move(ctx)) );
|
||||
}
|
||||
}
|
||||
@@ -2219,7 +2218,7 @@ namespace boost { namespace leaf {
|
||||
inline decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...)) capture_impl(is_result_tag<R, true>, context_ptr && ctx, F && f, A... a)
|
||||
{
|
||||
auto active_context = activate_context(*ctx);
|
||||
augment_id aug;
|
||||
error_monitor cur_err;
|
||||
try
|
||||
{
|
||||
if( auto && r = std::forward<F>(f)(std::forward<A>(a)...) )
|
||||
@@ -2241,7 +2240,7 @@ namespace boost { namespace leaf {
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
ctx->captured_id_ = aug.get_error();
|
||||
ctx->captured_id_ = cur_err.assigned_error_id();
|
||||
throw_exception( capturing_exception(std::current_exception(), std::move(ctx)) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace boost { namespace leaf {
|
||||
inline decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...)) capture_impl(is_result_tag<R, false>, context_ptr && ctx, F && f, A... a)
|
||||
{
|
||||
auto active_context = activate_context(*ctx);
|
||||
augment_id aug;
|
||||
error_monitor cur_err;
|
||||
try
|
||||
{
|
||||
return std::forward<F>(f)(std::forward<A>(a)...);
|
||||
@@ -115,7 +115,7 @@ namespace boost { namespace leaf {
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
ctx->captured_id_ = aug.get_error();
|
||||
ctx->captured_id_ = cur_err.assigned_error_id();
|
||||
throw_exception( capturing_exception(std::current_exception(), std::move(ctx)) );
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ namespace boost { namespace leaf {
|
||||
inline decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...)) capture_impl(is_result_tag<R, true>, context_ptr && ctx, F && f, A... a)
|
||||
{
|
||||
auto active_context = activate_context(*ctx);
|
||||
augment_id aug;
|
||||
error_monitor cur_err;
|
||||
try
|
||||
{
|
||||
if( auto && r = std::forward<F>(f)(std::forward<A>(a)...) )
|
||||
@@ -146,7 +146,7 @@ namespace boost { namespace leaf {
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
ctx->captured_id_ = aug.get_error();
|
||||
ctx->captured_id_ = cur_err.assigned_error_id();
|
||||
throw_exception( capturing_exception(std::current_exception(), std::move(ctx)) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
namespace boost { namespace leaf {
|
||||
|
||||
class augment_id
|
||||
class error_monitor
|
||||
{
|
||||
#if !defined(BOOST_LEAF_NO_EXCEPTIONS) && BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
|
||||
int const uncaught_exceptions_;
|
||||
@@ -27,7 +27,7 @@ namespace boost { namespace leaf {
|
||||
|
||||
public:
|
||||
|
||||
augment_id() noexcept:
|
||||
error_monitor() noexcept:
|
||||
#if !defined(BOOST_LEAF_NO_EXCEPTIONS) && BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
|
||||
uncaught_exceptions_(std::uncaught_exceptions()),
|
||||
#endif
|
||||
@@ -63,15 +63,14 @@ namespace boost { namespace leaf {
|
||||
return leaf_detail::new_id();
|
||||
}
|
||||
|
||||
error_id check_error() const noexcept
|
||||
error_id check() const noexcept
|
||||
{
|
||||
return leaf_detail::make_error_id(check_id());
|
||||
}
|
||||
|
||||
template <class... E>
|
||||
error_id get_error( E && ... e ) const noexcept
|
||||
error_id assigned_error_id() const noexcept
|
||||
{
|
||||
return leaf_detail::make_error_id(get_id()).load(std::forward<E>(e)...);
|
||||
return leaf_detail::make_error_id(get_id());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -202,7 +201,7 @@ namespace boost { namespace leaf {
|
||||
|
||||
std::tuple<Item...> p_;
|
||||
bool moved_;
|
||||
augment_id id_;
|
||||
error_monitor id_;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user