Replace custom error type with int

This commit is contained in:
Andreas Tsouchlos 2025-04-18 22:00:35 +02:00
parent 72121036a6
commit bbf039a596
2 changed files with 27 additions and 63 deletions

View File

@ -1,7 +1,6 @@
#include "tcp.hpp" #include "tcp.hpp"
#include <arpa/inet.h> #include <arpa/inet.h>
#include <array>
#include <cerrno> #include <cerrno>
#include <cstdint> #include <cstdint>
#include <expected> #include <expected>
@ -19,13 +18,13 @@
namespace { namespace {
std::expected<sockaddr_in, tcp::Error> get_server_address(const char* host, std::expected<sockaddr_in, int> get_server_address(const char* host,
uint16_t port) { uint16_t port) {
hostent* server = gethostbyname(host); hostent* server = gethostbyname(host);
if (server == nullptr) { if (server == nullptr) {
spdlog::error("tcp: get_host_by_name() failed with h_errno={}", spdlog::error("tcp: get_host_by_name() failed with h_errno={}",
h_errno); h_errno);
return std::unexpected{tcp::Error::FailedToResolveHost}; return std::unexpected{h_errno};
} }
sockaddr_in address{}; sockaddr_in address{};
@ -44,7 +43,7 @@ std::expected<sockaddr_in, tcp::Error> get_server_address(const char* host,
namespace tcp { namespace tcp {
[[nodiscard]] std::expected<void, Error> [[nodiscard]] std::expected<void, int>
NonBlockingClient::connect(HostString host, uint16_t port) { NonBlockingClient::connect(HostString host, uint16_t port) {
/// Resolve host /// Resolve host
@ -65,17 +64,9 @@ NonBlockingClient::connect(HostString host, uint16_t port) {
sizeof(serverAddress)); sizeof(serverAddress));
if (connectRes < 0) { if (connectRes < 0) {
if (errno == EALREADY) { spdlog::error("tcp::NonBlockingClient: connect() failed with errno={}",
spdlog::error( errno);
"tcp::NonBlockingClient: connect() failed with errno={}", return std::unexpected{errno};
errno);
return std::unexpected{Error::OtherOperationInProgress};
} else if (errno != EINPROGRESS) {
spdlog::error(
"tcp::NonBlockingClient: connect() failed with errno={}",
errno);
return std::unexpected{Error::FailedToStartConnecting};
}
} }
m_startedNewConAttemt = true; m_startedNewConAttemt = true;
@ -83,7 +74,7 @@ NonBlockingClient::connect(HostString host, uint16_t port) {
return {}; return {};
} }
[[nodiscard]] std::expected<ConnectionStatus, Error> [[nodiscard]] std::expected<ConnectionStatus, int>
NonBlockingClient::get_last_connection_status() { NonBlockingClient::get_last_connection_status() {
if (!m_startedNewConAttemt) return m_lastKnownConStatus; if (!m_startedNewConAttemt) return m_lastKnownConStatus;
@ -102,7 +93,7 @@ NonBlockingClient::get_last_connection_status() {
if (getsockopt(m_socket, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { if (getsockopt(m_socket, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
spdlog::error( spdlog::error(
"tcp::NonBlockingClient: getsockopt() failed with errno={}", errno); "tcp::NonBlockingClient: getsockopt() failed with errno={}", errno);
return std::unexpected{Error::FailedToReadSocketError}; return std::unexpected{errno};
} }
if (err == 0) { if (err == 0) {
@ -134,13 +125,14 @@ void NonBlockingClient::disconnect() {
close_socket(); close_socket();
} }
[[nodiscard]] std::expected<int, Error> [[nodiscard]] std::expected<int, int>
NonBlockingClient::send(std::span<const char> data) { NonBlockingClient::send(std::span<const char> data) {
// TODO: Do we need this?
auto conRes = get_last_connection_status(); auto conRes = get_last_connection_status();
if (!conRes) return std::unexpected{conRes.error()}; if (!conRes) return std::unexpected{conRes.error()};
if (conRes != ConnectionStatus::Successful) { if (conRes != ConnectionStatus::Successful) {
spdlog::error("tcp::NonBlockingClient: Socket not connected"); spdlog::error("tcp::NonBlockingClient: Socket not connected");
return std::unexpected{Error::SocketNotConnected}; return std::unexpected{ENOTCONN};
} }
const int bytesWritten = const int bytesWritten =
@ -149,15 +141,7 @@ NonBlockingClient::send(std::span<const char> data) {
if (bytesWritten <= 0) { if (bytesWritten <= 0) {
spdlog::error("tcp::NonBlockingClient: send() failed with errno={}", spdlog::error("tcp::NonBlockingClient: send() failed with errno={}",
errno); errno);
return std::unexpected{errno};
switch (errno) {
case EWOULDBLOCK:
return std::unexpected{Error::BufferFull};
case EALREADY:
return std::unexpected{Error::OtherOperationInProgress};
default:
return std::unexpected{Error::SendFailed};
}
} }
return bytesWritten; return bytesWritten;
@ -179,7 +163,7 @@ bool NonBlockingClient::data_available() {
return (m_pfdIn.revents & POLLIN); return (m_pfdIn.revents & POLLIN);
} }
[[nodiscard]] std::expected<int, Error> [[nodiscard]] std::expected<int, int>
NonBlockingClient::recv(std::span<char> buffer) { NonBlockingClient::recv(std::span<char> buffer) {
const int bytesReceived = const int bytesReceived =
::recv(m_socket, (char*)buffer.data(), buffer.size(), 0); ::recv(m_socket, (char*)buffer.data(), buffer.size(), 0);
@ -187,13 +171,7 @@ NonBlockingClient::recv(std::span<char> buffer) {
if (bytesReceived < 0) { if (bytesReceived < 0) {
spdlog::error("tcp::NonBlockingClient: recv() failed with errno={}", spdlog::error("tcp::NonBlockingClient: recv() failed with errno={}",
errno); errno);
return std::unexpected{errno};
switch (errno) {
case EWOULDBLOCK:
return std::unexpected{Error::NoDataAvailable};
default:
return std::unexpected{Error::RecvFailed};
}
} }
return {bytesReceived}; return {bytesReceived};
} }
@ -214,12 +192,12 @@ void NonBlockingClient::close_socket() {
m_pfdIn.fd = -1; m_pfdIn.fd = -1;
} }
[[nodiscard]] std::expected<void, Error> NonBlockingClient::create_socket() { [[nodiscard]] std::expected<void, int> NonBlockingClient::create_socket() {
m_socket = socket(AF_INET, SOCK_STREAM, 0); m_socket = socket(AF_INET, SOCK_STREAM, 0);
if (m_socket < 1) { if (m_socket < 1) {
spdlog::error("tcp::NonBlockingClient: socket() failed with errno={}", spdlog::error("tcp::NonBlockingClient: socket() failed with errno={}",
errno); errno);
return std::unexpected{Error::FailedToCreateSocket}; return std::unexpected{errno};
} }
m_pfdOut.fd = m_socket; m_pfdOut.fd = m_socket;
@ -230,26 +208,26 @@ void NonBlockingClient::close_socket() {
spdlog::error("tcp::NonBlockingClient: fcntl() failed with errno={}", spdlog::error("tcp::NonBlockingClient: fcntl() failed with errno={}",
errno); errno);
close_socket(); close_socket();
return std::unexpected{Error::FailedToCreateSocket}; return std::unexpected{errno};
} }
if (fcntl(m_socket, F_SETFL, (currentFlags) | O_NONBLOCK) == -1) { if (fcntl(m_socket, F_SETFL, (currentFlags) | O_NONBLOCK) == -1) {
spdlog::error("tcp::NonBlockingClient: fcntl() failed with errno={}", spdlog::error("tcp::NonBlockingClient: fcntl() failed with errno={}",
errno); errno);
close_socket(); close_socket();
return std::unexpected{Error::FailedToCreateSocket}; return std::unexpected{errno};
} }
return {}; return {};
} }
[[nodiscard]] std::expected<bool, Error> [[nodiscard]] std::expected<bool, int>
NonBlockingClient::new_error_codes_available() { NonBlockingClient::new_error_codes_available() {
int ret = poll(&m_pfdOut, 1, 0); int ret = poll(&m_pfdOut, 1, 0);
if (ret < 0) { if (ret < 0) {
spdlog::error("tcp::NonBlockingClient: poll() failed with errno={}", spdlog::error("tcp::NonBlockingClient: poll() failed with errno={}",
errno); errno);
return std::unexpected{Error::FailedToReadSocketError}; return std::unexpected{errno};
} }
return (ret == 0); return (ret == 0);

View File

@ -24,20 +24,6 @@
namespace tcp { namespace tcp {
enum class Error {
FailedToCreateSocket,
FailedToStartConnecting,
FailedToReadSocketError,
FailedToResolveHost,
OtherOperationInProgress,
SocketNotConnected,
BufferFull,
NoDataAvailable,
SendFailed,
RecvFailed,
};
enum class ConnectionStatus { enum class ConnectionStatus {
AttemptingConnection, AttemptingConnection,
Successful, Successful,
@ -63,19 +49,19 @@ using HostString = std::array<char, 64>;
class NonBlockingClient { class NonBlockingClient {
public: public:
// clang-format off // clang-format off
[[nodiscard]] std::expected<void, Error> [[nodiscard]] std::expected<void, int>
connect(HostString host, uint16_t port); connect(HostString host, uint16_t port);
// clang-format off // clang-format off
void disconnect(); void disconnect();
[[nodiscard]] std::expected<ConnectionStatus, Error> [[nodiscard]] std::expected<ConnectionStatus, int>
get_last_connection_status(); get_last_connection_status();
bool data_available(); bool data_available();
[[nodiscard]] std::expected<int, Error> recv(std::span<char> buffer); [[nodiscard]] std::expected<int, int> recv(std::span<char> buffer);
[[nodiscard]] std::expected<int, Error> send(std::span<const char> data); [[nodiscard]] std::expected<int, int> send(std::span<const char> data);
private: private:
int m_socket = -1; int m_socket = -1;
@ -87,8 +73,8 @@ private:
void close_socket(); void close_socket();
[[nodiscard]] std::expected<void, Error> create_socket(); [[nodiscard]] std::expected<void, int> create_socket();
[[nodiscard]] std::expected<bool, Error> new_error_codes_available(); [[nodiscard]] std::expected<bool, int> new_error_codes_available();
}; };
} // namespace tcp } // namespace tcp