Currently, the error type of librbd is int, which contains an error code of system_error category. Each function uses their own meaning for different error codes, also a code can be used for different situations, e.g. PreRemoveRequest returns EBUSY when an image has watchers, on acquiring a lock, or when the image is being migrated. Librados uses the same int as an error type, however neorados uses boost::system::error_code. Latest version of boost::system::error_code is {std::error_code, std::source_location*}. And std::error_code is {int, error_category*} (in stdlibc++ and libcxx). It is possible to use custom error types, internally, however user-facing API have to use a popular type such as std or boost error_code, otherwise users would have to convert error types. As std::error_code is the standard error type, and boost::system::error_code is convertible to it Various alternative approaches to errors, such as Boost.LEAF, Boost.Outcome and the corresponding std::error p1028 proposal, all of them are compatible with std(boost)::error_code. As std::error_code is a pair of an int and a pointer, it fits into two registers (eax:rdx), so changing result type from int to std::error_code basically adds one instruction: std::error_code f() { return SomeErrEnum::Code1; } with properly defined std::is_error_code_enum<SomeErrEnum> trait, and a SomeErrCategory type with a corresponding error category global value, compiles to f(): mov edx, OFFSET some_category_var mov eax, 1 ret Full code - https://godbolt.org/z/K7vv5h8oo Although there are corner cases such as surprisingly ineffective error_category& cat() { static SomeErrCategory c; return c; } where "static" requires branching for a guard variable, it is possible to keep overhead to adding single instruction for the error category. Back to the librbd. It is indeed not possible to simply change it's C++ API from returning int to error_code. Also, we cannot add overloads with different return types, we'd have to also change arguments. Passing error_code as an output parameter works int flatten(); // current API void flatten(std::error_code& ec); // alternative API but it doesn't look great, ideally we'd rather use "std::expected<T, error_code> f()" and not "void f(T& out, error_code& ec)". We can also add asynchronous API like in neorados, with CompletionTokens and callbacks that receive error_code. However, much of librbd code is synchronous (Operations), so rewriting it to an async code would needlessly complicate things. Is there a way to make librbd return std::error_code, so that we could use different error categories, enums, for more distinct error codes? _______________________________________________ Dev mailing list -- dev@xxxxxxx To unsubscribe send an email to dev-leave@xxxxxxx