Re: [Capy review] Some questions

Andrzej Krzemienski via Boost <[email protected]> Thu, 25 Jun 2026 22:24:57 +0200
Newsgroups gmane.comp.lib.boost.devel
Message-ID <CAOenAXhxDKgxPPQ9xyX9FwBL1V6bgRoBx6WyKoc1p4=ioQAU4w@mail.gmail.com>
śr., 24 cze 2026 o 11:50 Ruben Perez <[email protected]> napisał(a):

> >>
> >> 3) Asio has the concept of error dispositions [6]. In a nutshell, these
> are
> >> a generalization of error codes, so custom error types can be used in
> error
> >> code-aware functionality, like when_any. This is useful in code using
> >> specialized types. Future candidate Boost.Http uses this in its router
> [8],
> >> and I intended to use it as a way to attach error messages in my
> database
> >> libraries. I discuss my use case in more detail in this issue [9]. Have
> you
> >> considered the feature?
> >
> >
> >> [6]
> >>
> https://www.boost.org/doc/libs/latest/doc/html/boost_asio/reference/Disposition.html
> >
> >
> > Would you be able to provide an example illustrating how you would use
> this?
> >
>
> My use case is including a diagnostic string returned by the server in
> the error type. For instance:
>
> struct extended_error
> {
>     std::error_code code;
>     std::string diag;
> }; // complete type in my postgres library here [1]
>
> Then you can define your Asio function like this:
>
> class connection {
> public:
>     template <asio::completion_token_for<void(extended_error)>
> CompletionToken>
>     auto async_connect(const connect_params& params, CompletionToken&&
> token);
> };  // complete type here [2]
>
> With Capy, I currently have:
>
> class connection {
> public:
>     // *diag will be populated in case of server error
>     boost::capy::io_task<> connect(connect_params params, std::string*
> diag = nullptr);
> };
>
> Before anyone asks, I can go down the path of "only network errors are
> failures" and write:
>
> // Succeeds if the server rejects the connection - populates
> server_errors in this case
> boost::capy::io_task<> connect(connect_params params, extended_error&
> server_errors);
>
> This is adequate for low-level functionality, but becomes hostile as
> you build higher level functionality.
>
> For now, I've encoded the SQLSTATE returned by the server as a
> std::error_code, so the user gets _some_ diagnostics even if they
> didn't use the output parameter [3].
>

Isn't it like lower layers of the server deciding what the users will see
in the API?

Regards,
&rzej;


>
> Because extended_error is no longer trivially copyable, I don't know
> the performance implications that such dispositions may have. I am
> open to discussion of what's the best way of doing this with Capy. It
> doesn't have to be dispositions.
>
> Another case for dispositions would be supporting custom error types,
> like boost::system::error_code. ATM this doesn't compile:
>
> capy::task<boost::system::error_code> my_task() { co_return {}; }
> capy::task<void> co_main() {
>     co_await capy::timeout(my_task(), 1s);
> }
>
> I personally don't need this.
>
> Thanks,
> Ruben.
>
> [1]
> https://github.com/anarthal/nativepg/blob/master/include/nativepg/extended_error.hpp
> [2]
> https://github.com/anarthal/nativepg/blob/master/include/nativepg/connection.hpp
> [3]
> https://github.com/anarthal/nativepg/blob/master/include/nativepg/sqlstate.hpp
>
_______________________________________________
Boost mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://lists.boost.org/mailman3/lists/boost.lists.boost.org/
Archived at: https://lists.boost.org/archives/list/[email protected]/message/WYJPUR2SNRCHWFY46ME43NG42Q5DW5DD/