refactor: simplify error logging in epoll functions and separate error handling logic

This commit is contained in:
Quinten 2025-11-12 13:09:34 +01:00
parent 05b8ebf61b
commit 59e29f1639
2 changed files with 46 additions and 55 deletions

View File

@ -77,7 +77,7 @@ void Server::add(ASocket &socket, Client *client)
event.data.fd = fd; event.data.fd = fd;
if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &event) == -1) if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &event) == -1)
{ {
Log::error(socket.toString() + ": epoll_ctl ADD failed with error: " + std::strerror(errno)); Log::error(socket.toString() + ": epoll_ctl ADD failed");
throw std::runtime_error("epoll_ctl ADD failed"); throw std::runtime_error("epoll_ctl ADD failed");
} }
Log::debug(socket.toString() + ": added to epoll"); Log::debug(socket.toString() + ": added to epoll");
@ -96,7 +96,7 @@ void Server::remove(ASocket &socket)
Log::debug(socket.toString() + " was already closed or removed from epoll"); Log::debug(socket.toString() + " was already closed or removed from epoll");
return; return;
} }
Log::error(socket.toString() + ": epoll_ctl DEL failed with error: " + std::string(std::strerror(errno))); Log::error(socket.toString() + ": epoll_ctl DEL failed");
throw std::runtime_error("epoll_ctl DEL failed"); throw std::runtime_error("epoll_ctl DEL failed");
} }
socketToClient_.erase(fd); socketToClient_.erase(fd);
@ -156,7 +156,7 @@ ServerSocket &Server::getListener(int fd) const
return *listener; return *listener;
} }
} }
Log::error("Listener not found for fd: " + std::to_string(fd) + ": " + std::strerror(errno)); Log::error("Listener not found for fd: " + std::to_string(fd));
throw std::runtime_error("Listener not found for fd: " + std::to_string(fd)); throw std::runtime_error("Listener not found for fd: " + std::to_string(fd));
} }
@ -190,7 +190,7 @@ void Server::writable(int client_fd) const
ev.data.fd = client_fd; ev.data.fd = client_fd;
if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, client_fd, &ev) == -1) if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, client_fd, &ev) == -1)
{ {
Log::error(socket.toString() + ": epoll_ctl MOD failed with error: " + std::string(std::strerror(errno))); Log::error(socket.toString() + ": epoll_ctl MOD failed");
throw std::runtime_error("epoll_ctl MOD failed"); throw std::runtime_error("epoll_ctl MOD failed");
} }
} }
@ -212,7 +212,7 @@ void Server::update(const ASocket &socket) const
Log::debug(socket.toString() + ": was already closed or removed from epoll"); Log::debug(socket.toString() + ": was already closed or removed from epoll");
return; return;
} }
Log::error(socket.toString() + ": epoll_ctl MOD failed with error: " + std::string(std::strerror(errno))); Log::error(socket.toString() + ": epoll_ctl MOD failed");
throw std::runtime_error("epoll_ctl MOD failed"); throw std::runtime_error("epoll_ctl MOD failed");
} }
} }
@ -237,53 +237,36 @@ void Server::handleEpollHangUp(struct epoll_event *event) const
socket.callback(); socket.callback();
return; return;
} }
Log::warning(socket.toString() + ": Epoll hang up with error: " + std::string(std::strerror(errno))); Log::warning(socket.toString() + ": Epoll hang up");
} }
void Server::handleEvent(struct epoll_event *event) void Server::handleEpollError(struct epoll_event *event)
{
Log::trace(LOCATION);
if ((event->events & EPOLLERR) > 0)
{ {
int fd = event->data.fd; int fd = event->data.fd;
Log::error("Epoll error on fd " + std::to_string(fd) + ": " + std::strerror(errno)); Log::error("Epoll error on fd " + std::to_string(fd));
// If this is a listener socket, remove just that listener
if (listener_fds_.contains(fd))
{
try
{
remove(getListener(fd));
}
catch (const std::exception &e)
{
Log::warning(std::string("Failed to remove listener on EPOLLERR: ") + e.what());
}
close(fd);
listener_fds_.erase(fd);
}
else
{
// Non-listener sockets: resolve to client/socket and handle gracefully
try try
{ {
Client &client = getClient(fd); Client &client = getClient(fd);
ASocket &socket = client.getSocket(fd); ASocket &socket = client.getSocket(fd);
if (socket.getType() == ASocket::Type::CGI_SOCKET) switch (socket.getType())
{
Log::info(socket.toString() + ": EPOLLERR removing socket");
remove(socket);
close(fd);
}
else if (socket.getType() == ASocket::Type::CLIENT_SOCKET)
{ {
case ASocket::Type::CLIENT_SOCKET:
Log::warning(socket.toString() + ": EPOLLERR disconnecting client"); Log::warning(socket.toString() + ": EPOLLERR disconnecting client");
disconnect(client); disconnect(client);
} break;
else case ASocket::Type::SERVER_SOCKET:
{ Log::warning(socket.toString() + ": EPOLLERR removing server socket");
remove(socket);
close(fd);
listener_fds_.erase(fd);
break;
case ASocket::Type::TIMER_SOCKET:
case ASocket::Type::CGI_SOCKET:
default:
Log::warning(socket.toString() + ": EPOLLERR removing auxiliary socket"); Log::warning(socket.toString() + ": EPOLLERR removing auxiliary socket");
remove(socket); remove(socket);
close(fd); close(fd);
break;
} }
} }
catch (const std::exception &e) catch (const std::exception &e)
@ -292,9 +275,16 @@ void Server::handleEvent(struct epoll_event *event)
close(fd); close(fd);
} }
} }
return;
void Server::handleEvent(struct epoll_event *event)
{
Log::trace(LOCATION);
if ((event->events & EPOLLERR) > 0)
{
handleEpollError(event);
// return;
} }
if ((event->events & EPOLLHUP) > 0) else if ((event->events & EPOLLHUP) > 0)
{ {
handleEpollHangUp(event); handleEpollHangUp(event);
} }

View File

@ -58,6 +58,7 @@ class Server
void pollSockets(); void pollSockets();
void handleEpoll(struct epoll_event *events, int max_events); void handleEpoll(struct epoll_event *events, int max_events);
void handleEpollError(struct epoll_event *event);
void handleEpollHangUp(struct epoll_event *event) const; void handleEpollHangUp(struct epoll_event *event) const;
void handleEvent(struct epoll_event *event); void handleEvent(struct epoll_event *event);
void handleConnection(struct epoll_event *event); void handleConnection(struct epoll_event *event);