[LEAF] Loss of error_id

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[LEAF] Loss of error_id

Boost - Dev mailing list
In the noexcept case, what happens in the Error-Handling function if the
error_id generated by the Error-Reporting function is lost by the
intermediate functions?

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [LEAF] Loss of error_id

Boost - Dev mailing list
On Mon, May 25, 2020 at 7:34 AM Bjorn Reese via Boost <[hidden email]>
wrote:

> In the noexcept case, what happens in the Error-Handling function if the
> error_id generated by the Error-Reporting function is lost by the
> intermediate functions?
>

You mean, as in:

leaf::result<float> f(); // Returns a float or an error

leaf::result<int> g() // Returns an int or an error
{
  (void) f(); // Discard the float or the error returned by f
  return 42;
}

void error_handler()
{
  leaf::try_handle_all(
    [ ]
    {
      LEAF_AUTO(answer, g());
      .... // Success! Use answer.
    },
    .... // Handle errors
  ); // Done handling errors, the context in the scope of try_handle_all is
destroyed.
}

At the time control returns back to our error_handler, any error objects
that were passed by f to LEAF are stored in a context (or, in case there
weren't any error handlers that need them, were discarded on the spot).
When the context in the scope of leaf::try_handle_all is destroyed, its
contents are destroyed as well.

To access an error object when handling errors, you need the correct
error_id. Had g reported another failure after discarding whatever f
returned, when that error reaches our error_handler, if the context still
contains any error objects associated with the error_id g discarded, they
can't be accessed because the new error has a different error_id.

You get a unique error_id when you call leaf::new_error. It's like a serial
number of this particular failure. You can print error_ids in diagnostic
messages; this can help detect bugs where a failure was erroneously
discarded (not handled).

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [LEAF] Loss of error_id

Boost - Dev mailing list
On Mon, May 25, 2020 at 1:21 PM Emil Dotchevski <[hidden email]>
wrote:
> At the time control returns back to our error_handler, any error objects
that were passed by f to LEAF are stored in a context

To clarify, I specifically mean leaf::context<E...>.

>

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [LEAF] Loss of error_id

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
On 2020-05-25 22:21, Emil Dotchevski via Boost wrote:

> You mean, as in:

Good example.

> leaf::result<float> f(); // Returns a float or an error
>
> leaf::result<int> g() // Returns an int or an error
> {
>    (void) f(); // Discard the float or the error returned by f
>    return 42;
> }

Suppose there is also an h() function in the call stack that is being
called by the error_handler() function instead of g():

   leaf::result<int> h()
   {
       auto res = g();
       // How to detect that f() raised an error without knowing
       // its error_id?
       return res;
   }

Can this function detect that someone further up the call stack has
already raised an error? Similar to std::uncaught_exceptions()?

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [LEAF] Loss of error_id

Boost - Dev mailing list
On Tue, May 26, 2020 at 2:53 PM Bjorn Reese via Boost <[hidden email]>
wrote:

>
> On 2020-05-25 22:21, Emil Dotchevski via Boost wrote:
>
> > You mean, as in:
>
> Good example.
>
> > leaf::result<float> f(); // Returns a float or an error
> >
> > leaf::result<int> g() // Returns an int or an error
> > {
> >    (void) f(); // Discard the float or the error returned by f
> >    return 42;
> > }
>
> Suppose there is also an h() function in the call stack that is being
> called by the error_handler() function instead of g():
>
>    leaf::result<int> h()
>    {
>        auto res = g();
>        // How to detect that f() raised an error without knowing
>        // its error_id?
>        return res;
>    }
>
> Can this function detect that someone further up the call stack has
> already raised an error? Similar to std::uncaught_exceptions()?

If g() still does (void) f(); (that is, discards the error), by analogy
this is like try { f(); } catch(...) { }, so I don't understand why h()
would care.

That said, you can detect that f() reported an error. This is exposed
through the augment_id API: https://zajo.github.io/leaf/#augment_id. You
can instantiate this class, and then later call check_error() to see if
some function (from this thread) has reported any errors since then:

leaf::augment_id id;
(void) f();
(void) g();
if( id.check_error() ) {
  // f() or g(), or something they call, reported at least one error.
  // The error(s) may have been discarded or handled.
}

Naturally, this is not common. Generally, we handle, rather than discard,
all reported errors.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost