refactor: Use expected<void, error> instead of optional<error> (#2565)

Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
This commit is contained in:
emrearıyürek
2025-09-15 14:54:09 +02:00
committed by GitHub
parent 26112d17f8
commit e996f2b7ab
19 changed files with 315 additions and 259 deletions

View File

@@ -143,9 +143,9 @@ public:
*
* @param response The response to send.
* @param yield The yield context.
* @return An error if the operation failed or nullopt if it succeeded.
* @return An error if the operation fails, otherwise nothing.
*/
virtual std::optional<Error>
virtual std::expected<void, Error>
send(Response response, boost::asio::yield_context yield) = 0;
/**

View File

@@ -147,9 +147,9 @@ makeConnection(
tagDecoratorFactory
);
sslConnection->setTimeout(std::chrono::seconds{10});
auto const maybeError = sslConnection->sslHandshake(yield);
if (maybeError.has_value())
return std::unexpected{fmt::format("SSL handshake error: {}", maybeError->message())};
auto const expectedSuccess = sslConnection->sslHandshake(yield);
if (not expectedSuccess.has_value())
return std::unexpected{fmt::format("SSL handshake error: {}", expectedSuccess.error().message())};
connection = std::move(sslConnection);
} else {

View File

@@ -70,8 +70,8 @@ SubscriptionContext::send(std::shared_ptr<std::string> message)
}
tasksGroup_.spawn(yield_, [this, message = std::move(message)](boost::asio::yield_context innerYield) mutable {
auto const maybeError = connection_.get().sendShared(std::move(message), innerYield);
if (maybeError.has_value() and errorHandler_(*maybeError, connection_)) {
auto const expectedSuccess = connection_.get().sendShared(std::move(message), innerYield);
if (not expectedSuccess.has_value() and errorHandler_(expectedSuccess.error(), connection_)) {
connection_.get().close(innerYield);
gotError_ = true;
}

View File

@@ -365,9 +365,9 @@ ConnectionHandler::processRequest(
auto response = handleRequest(connection, subscriptionContext, request, yield);
LOG(log_.trace()) << connection.tag() << "Sending response: " << response.message();
auto const maybeError = connection.send(std::move(response), yield);
if (maybeError.has_value()) {
return handleError(maybeError.value(), connection);
auto const expectedSuccess = connection.send(std::move(response), yield);
if (not expectedSuccess.has_value()) {
return handleError(expectedSuccess.error(), connection);
}
return std::nullopt;
}

View File

@@ -62,7 +62,7 @@ public:
virtual std::expected<ConnectionPtr, Error>
upgrade(util::TagDecoratorFactory const& tagDecoratorFactory, boost::asio::yield_context yield) = 0;
virtual std::optional<Error>
virtual std::expected<void, Error>
sendRaw(
boost::beast::http::response<boost::beast::http::string_body> response,
boost::asio::yield_context yield
@@ -123,7 +123,7 @@ public:
HttpConnection&
operator=(HttpConnection const& other) = delete;
std::optional<Error>
std::expected<void, Error>
sslHandshake(boost::asio::yield_context yield)
requires IsSslTcpStream<StreamType>
{
@@ -132,11 +132,11 @@ public:
auto const bytesUsed =
stream_.async_handshake(boost::asio::ssl::stream_base::server, buffer_.cdata(), yield[error]);
if (error)
return error;
return std::unexpected{error};
buffer_.consume(bytesUsed);
return std::nullopt;
return {};
}
bool
@@ -145,7 +145,7 @@ public:
return false;
}
std::optional<Error>
std::expected<void, Error>
sendRaw(
boost::beast::http::response<boost::beast::http::string_body> response,
boost::asio::yield_context yield
@@ -160,7 +160,7 @@ public:
timeout_ = newTimeout;
}
std::optional<Error>
std::expected<void, Error>
send(Response response, boost::asio::yield_context yield) override
{
auto httpResponse = std::move(response).intoHttpResponse();

View File

@@ -47,15 +47,15 @@ public:
{
}
std::optional<Error>
std::expected<void, Error>
send(T message, boost::asio::yield_context yield)
{
if (error_)
return error_;
return std::unexpected{error_};
queue_.push(std::move(message));
if (isSending_)
return std::nullopt;
return {};
isSending_ = true;
while (not queue_.empty() and not error_) {
@@ -65,8 +65,8 @@ public:
}
isSending_ = false;
if (error_)
return error_;
return std::nullopt;
return std::unexpected{error_};
return {};
}
};

View File

@@ -59,7 +59,7 @@ class WsConnectionBase : public Connection {
public:
using Connection::Connection;
virtual std::optional<Error>
virtual std::expected<void, Error>
sendShared(std::shared_ptr<std::string> message, boost::asio::yield_context yield) = 0;
};
@@ -108,14 +108,14 @@ public:
WsConnection&
operator=(WsConnection const&) = delete;
std::optional<Error>
std::expected<void, Error>
performHandshake(boost::asio::yield_context yield)
{
Error error;
stream_.async_accept(initialRequest_, yield[error]);
if (error)
return error;
return std::nullopt;
return std::unexpected{error};
return {};
}
bool
@@ -124,7 +124,7 @@ public:
return true;
}
std::optional<Error>
std::expected<void, Error>
sendShared(std::shared_ptr<std::string> message, boost::asio::yield_context yield) override
{
return sendingQueue_.send(std::move(message), yield);
@@ -140,7 +140,7 @@ public:
stream_.set_option(wsTimeout);
}
std::optional<Error>
std::expected<void, Error>
send(Response response, boost::asio::yield_context yield) override
{
return sendingQueue_.send(std::move(response), yield);
@@ -206,9 +206,9 @@ makeWsConnection(
auto connection = std::make_unique<WsConnection<StreamType>>(
std::forward<StreamType>(stream), std::move(ip), std::move(buffer), std::move(request), tagDecoratorFactory
);
auto maybeError = connection->performHandshake(yield);
if (maybeError.has_value())
return std::unexpected{maybeError.value()};
auto const expectedSuccess = connection->performHandshake(yield);
if (not expectedSuccess.has_value())
return std::unexpected{expectedSuccess.error()};
return connection;
}