boostorg / leaf

Lightweight Error Augmentation Framework
Boost Software License 1.0
312 stars 48 forks source link

Should LEAF provide allocating context for simple multi-thread error handling? #63

Closed Snarpix closed 10 months ago

Snarpix commented 1 year ago

If I want to run user-provided function on my thread pool and return result, currently I have to ask user to provide error_handlers to use leaf::make_shared_context to allocate memory for error objects. This is not very convenient.

Other option is that I can force user to handle transportation of leaf::result between threads. In that case user will call make_shared_context, but that makes use of my library inconvenient.

In simplest case I just want to transport all errors between threads by allocating memory for error objects and allow user code to handle them. Maybe LEAF should provide such context?

zajo commented 1 year ago

Yes this is on my list of things to do.

zajo commented 11 months ago

I have not updated the documentation yet, but this is pretty much done, check it out in the feature/dynamic_capture branch.

I've decided to do away with the ability of exceptions to carry a capture directly, now if you want to capture some error objects and carry them around, you put them in a leaf::result<T>. There is a new error object type called dynamic_capture, so:

auto r = try_handle_some(
    []
    {
        ....
    },
    []( leaf::dynamic_capture const & cap )
    {
        return cap;
    } );

And now r has everything that dynamic_capture captured. The caveat is that it only captures things for which there isn't an active handler currently.

Of course now verbose_diagnostic_info is implemented in terms of dynamic_capture internally.

Feedback welcome.

Snarpix commented 10 months ago

Thanks, that looks amazing!

Only one note: It will be convenient if there will be a function in leaf that wraps around try_handle_some with dynamic_capture. It's a common pattern to just catch everything. Something like:

      // Pseudocode
      std::shared_ptr<leaf::polymorphic_context> ctx = leaf::make_shared_context(leaf::dynamic_capture_ctx{});
      return leaf::capture(ctx, &task);

But for dynamic_capture:

      return leaf::dynamic_capture_all(&task);

Thank you, it's a really cool feature!

zajo commented 10 months ago

@Snarpix see current develop branch. I deleted the dynamic_capture functionalety, replaced by try_capture_all which works the way you suggested.