From 50904ff45119c4e06234ee1578c6867bd25bf6cf Mon Sep 17 00:00:00 2001 From: Oleg Kl Date: Fri, 10 Jul 2026 17:23:40 +0500 Subject: [PATCH 1/4] refactor(exceptions): #25: add ExceptionResponseHandler to handle all exception --- src/api/exception-response-handler.cpp | 15 +++++++++++++++ src/api/exception-response-handler.h | 11 +++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/api/exception-response-handler.cpp create mode 100644 src/api/exception-response-handler.h diff --git a/src/api/exception-response-handler.cpp b/src/api/exception-response-handler.cpp new file mode 100644 index 0000000..26d030f --- /dev/null +++ b/src/api/exception-response-handler.cpp @@ -0,0 +1,15 @@ +#include "exception-response-handler.h" + +#include + +drogon::HttpResponsePtr ExceptionResponseHandler::handle(const std::string& status, const std::string& message, drogon::HttpStatusCode status_code) +{ + Json::Value responseBody; + responseBody["status"] = status; + responseBody["message"] = message; + + auto response = drogon::HttpResponse::newHttpJsonResponse(responseBody); + response->setStatusCode(status_code); + + return response; +} diff --git a/src/api/exception-response-handler.h b/src/api/exception-response-handler.h new file mode 100644 index 0000000..a44a887 --- /dev/null +++ b/src/api/exception-response-handler.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +#include + +class ExceptionResponseHandler +{ +public: + [[nodiscard]] static drogon::HttpResponsePtr handle(const std::string& status, const std::string& message, drogon::HttpStatusCode status_code); +}; \ No newline at end of file From 9cf1bf167790de8ffa2e880a7d77ace5af0d822e Mon Sep 17 00:00:00 2001 From: Oleg Kl Date: Fri, 10 Jul 2026 17:24:20 +0500 Subject: [PATCH 2/4] refactor(exceptions): #25: add ExceptionResponseHandler overload to handle not 500 errors --- src/api/exception-response-handler.cpp | 7 +++++++ src/api/exception-response-handler.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/api/exception-response-handler.cpp b/src/api/exception-response-handler.cpp index 26d030f..3ee95d0 100644 --- a/src/api/exception-response-handler.cpp +++ b/src/api/exception-response-handler.cpp @@ -13,3 +13,10 @@ drogon::HttpResponsePtr ExceptionResponseHandler::handle(const std::string& stat return response; } + +drogon::HttpResponsePtr ExceptionResponseHandler::handle(const std::exception& exception) +{ + LOG_ERROR << "Exception occured: " << exception.what(); + + return ExceptionResponseHandler::handle("error", "Internal server error", drogon::k500InternalServerError); +} diff --git a/src/api/exception-response-handler.h b/src/api/exception-response-handler.h index a44a887..0418a69 100644 --- a/src/api/exception-response-handler.h +++ b/src/api/exception-response-handler.h @@ -7,5 +7,6 @@ class ExceptionResponseHandler { public: + [[nodiscard]] static drogon::HttpResponsePtr handle(const std::exception& exception); [[nodiscard]] static drogon::HttpResponsePtr handle(const std::string& status, const std::string& message, drogon::HttpStatusCode status_code); }; \ No newline at end of file From 24c62fc1ee6366f9849460c92c954e5f955c931b Mon Sep 17 00:00:00 2001 From: Oleg Kl Date: Fri, 10 Jul 2026 17:24:34 +0500 Subject: [PATCH 3/4] refactor(exceptions): #25: replace older exception handler --- src/api/features/to-dos/to-dos-controller.cpp | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/src/api/features/to-dos/to-dos-controller.cpp b/src/api/features/to-dos/to-dos-controller.cpp index 5ee7178..fc553b6 100644 --- a/src/api/features/to-dos/to-dos-controller.cpp +++ b/src/api/features/to-dos/to-dos-controller.cpp @@ -1,18 +1,7 @@ #include "to-dos-controller.h" #include "db_connection.h" +#include -// TODO(https://github.com/TourmalineCore/to-dos-api-cpp/issues/25): Create http exception handler or generic class for handling that type of errors -HttpResponsePtr ToDosController::createInternalServerErrorResponse(const std::string& error) const -{ - Json::Value jsonResponse; - jsonResponse["status"] = "Error"; - jsonResponse["message"] = "Internal server error"; - jsonResponse["error"] = error; - - auto resp = HttpResponse::newHttpJsonResponse(jsonResponse); - resp->setStatusCode(k500InternalServerError); - return resp; -} ToDosController::ToDosController() { @@ -48,9 +37,9 @@ void ToDosController::getToDos(const HttpRequestPtr& req, std::functionsetStatusCode(k200OK); callback(resp); } - catch (const std::exception& e) + catch (const std::exception& exception) { - callback(createInternalServerErrorResponse(e.what())); + callback(ExceptionResponseHandler::handle(exception)); } } @@ -79,9 +68,9 @@ void ToDosController::addToDo(const HttpRequestPtr& req, std::functionsetStatusCode(k201Created); callback(resp); } - catch (const std::exception& e) + catch (const std::exception& exception) { - callback(createInternalServerErrorResponse(e.what())); + callback(ExceptionResponseHandler::handle(exception)); } } @@ -114,9 +103,9 @@ void ToDosController::completeToDos(const HttpRequestPtr& req, std::functionsetStatusCode(k200OK); callback(resp); } - catch (const std::exception& e) + catch (const std::exception& exception) { - callback(createInternalServerErrorResponse(e.what())); + callback(ExceptionResponseHandler::handle(exception)); } } @@ -134,8 +123,8 @@ void ToDosController::deleteToDo(const HttpRequestPtr& req, std::functionsetStatusCode(k200OK); callback(resp); } - catch (const std::exception& e) + catch (const std::exception& exception) { - callback(createInternalServerErrorResponse(e.what())); + callback(ExceptionResponseHandler::handle(exception)); } } \ No newline at end of file From 0b1c2b3d4f37dbb97d897ebe13ebbf44f1b559a3 Mon Sep 17 00:00:00 2001 From: Oleg Kl Date: Fri, 10 Jul 2026 17:29:35 +0500 Subject: [PATCH 4/4] chore(exceptions): #25: add doxygen comments --- src/api/exception-response-handler.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/api/exception-response-handler.h b/src/api/exception-response-handler.h index 0418a69..6000bb0 100644 --- a/src/api/exception-response-handler.h +++ b/src/api/exception-response-handler.h @@ -7,6 +7,15 @@ class ExceptionResponseHandler { public: - [[nodiscard]] static drogon::HttpResponsePtr handle(const std::exception& exception); + /// @brief Creates a JSON HTTP error response with the specified status and message. + /// @param status Status value included in the JSON response body. + /// @param message Message included in the JSON response body. + /// @param status_code HTTP status code returned to the client. + /// @return JSON HTTP response. [[nodiscard]] static drogon::HttpResponsePtr handle(const std::string& status, const std::string& message, drogon::HttpStatusCode status_code); + + /// @brief Handles an unexpected exception and creates an internal server error response. + /// @param exception Exception caught while handling an HTTP request. + /// @return HTTP 500 JSON response. + [[nodiscard]] static drogon::HttpResponsePtr handle(const std::exception& exception); }; \ No newline at end of file