Re: [Capy review] Some questions

Ruben Perez via Boost <[email protected]> Wed, 24 Jun 2026 11:50:06 +0200
Newsgroups gmane.comp.lib.boost.devel
Message-ID <CACR-md+7rWKh8DhFiwndHSJ--tcoxGpEo6PQFL2zwa9bBHaanA@mail.gmail.com>
>>
>> 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].

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/KF2O3VRCH7BMVJNMBEBQHHZRTYX7I3D3/