Using try_ will now handle result<T> errors as well, see https://github.com/zajo/leaf/blob/feature/error_code/test/try_exception_and_... . With this, in your example instead of handle_all you can just use try_: leaf::try_( [i]() -> leaf::result<int> { LEAF_AUTO(r, f2(i)); (void) r; return 0; }, //handlers... ); The only difference is that in case f2 does not throw, try_ is not equivalent to handle_all but to handle_some, so the result<int> that will pop out of try_ should not be discarded (in case it is communicating an unmatched error). By the way, in this new iteration handle_some, handle_all and try_ don't require leaf::result<T>, they can work with any "result" type which defines .value() and .error(), as long as .error() returns std::error_code or leaf::error.