fix: improve error handling in Server event processing

This commit is contained in:
whaffman 2025-11-04 19:25:52 +01:00
parent cd1932762a
commit 6a354f6742
3 changed files with 59 additions and 15 deletions

@ -1 +1 @@
Subproject commit 1daf3e55aa913c8d5120a942b2513ca36d7309ac
Subproject commit 0a4c692fc618e0b8d26a8e6d9079c22c74345834

View File

@ -1,19 +1,17 @@
#include <webserv/router/Router.hpp> // for Router
#include <webserv/handler/ErrorHandler.hpp>
#include <webserv/http/RequestValidator.hpp>
#include <webserv/client/Client.hpp> // for Client
#include <webserv/config/AConfig.hpp> // for AConfig
#include <webserv/config/directive/ADirective.hpp> // for ADirective
#include <webserv/config/directive/DirectiveValue.hpp> // for DirectiveValue
#include <webserv/handler/CgiHandler.hpp> // for CgiHandler
#include <webserv/handler/CgiProcess.hpp> // for CgiProcess
#include <webserv/handler/FileHandler.hpp> // for FileHandler
#include <webserv/handler/URI.hpp> // for URI
#include <webserv/http/HttpRequest.hpp> // for HttpRequest
#include <webserv/log/Log.hpp> // for Log, LOCATION
#include <webserv/handler/RedirectHandler.hpp> // for RedirectHandler
#include <webserv/handler/ErrorHandler.hpp>
#include <webserv/handler/FileHandler.hpp> // for FileHandler
#include <webserv/handler/RedirectHandler.hpp> // for RedirectHandler
#include <webserv/handler/URI.hpp> // for URI
#include <webserv/http/HttpRequest.hpp> // for HttpRequest
#include <webserv/http/RequestValidator.hpp>
#include <webserv/log/Log.hpp> // for Log, LOCATION
#include <webserv/router/Router.hpp> // for Router
#include <exception> // for exception
#include <memory> // for unique_ptr, make_unique
@ -46,7 +44,7 @@ std::unique_ptr<AHandler> Router::handleRequest()
HttpRequest &request = client_->getHttpRequest();
HttpResponse &response = client_->getHttpResponse();
const AConfig *config = request.getUri().getConfig();
auto validator = std::make_unique<RequestValidator>(config, &request);
@ -70,6 +68,9 @@ std::unique_ptr<AHandler> Router::handleRequest()
catch (const std::exception &e)
{
Log::error("CGI process failed: " + std::string(e.what()));
// Ensure we return an error response instead of a null handler to avoid hanging/connection drops
ErrorHandler::createErrorResponse(500, response, config);
return nullptr;
}
}
else

View File

@ -241,9 +241,52 @@ void Server::handleEvent(struct epoll_event *event)
Log::trace(LOCATION);
if ((event->events & EPOLLERR) > 0)
{
Log::error("Epoll error on fd " + std::to_string(event->data.fd) + ": " + std::strerror(errno));
remove(getListener(event->data.fd));
close(event->data.fd);
int fd = event->data.fd;
Log::error("Epoll error on fd " + std::to_string(fd) + ": " + std::strerror(errno));
// 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
{
Client &client = getClient(fd);
ASocket &socket = client.getSocket(fd);
if (socket.getType() == ASocket::Type::CGI_SOCKET)
{
Log::info("EPOLLERR on CGI socket fd " + std::to_string(fd) + ", invoking callback");
socket.callback();
}
else if (socket.getType() == ASocket::Type::CLIENT_SOCKET)
{
Log::warning("EPOLLERR on client socket fd " + std::to_string(fd) + ", disconnecting client");
disconnect(client);
}
else
{
Log::warning("EPOLLERR on auxiliary socket fd " + std::to_string(fd) + ", removing");
remove(socket);
close(fd);
}
}
catch (const std::exception &e)
{
Log::warning(std::string("EPOLLERR on unknown/non-tracked fd, closing: ") + e.what());
close(fd);
}
}
return;
}
if ((event->events & EPOLLHUP) > 0)