oatpp-authkit/include/oatpp-authkit/handler/JsonErrorHandler.hpp
Uwe Schuster 081e0b36dc v0.2.1: wrap clean-lift headers in namespace oatpp_authkit
The four clean-lift headers (SecurityHeadersInterceptor,
BodySizeLimitInterceptor, JsonErrorHandler, RateLimiter) were copied
verbatim in v0.1.0 and left in the global namespace — consumers that
adopt the library alongside existing same-named classes (e.g. fewo-webapp
during the #417 swap) would hit ODR clashes.

Wrap them in the same namespace the v0.2 auth seams use. Patch bump; no
API surface change beyond the qualifier.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 21:53:21 +02:00

70 lines
2.3 KiB
C++

#ifndef HANDLER_JSON_ERROR_HANDLER_HPP
#define HANDLER_JSON_ERROR_HANDLER_HPP
#include "oatpp/web/server/handler/ErrorHandler.hpp"
#include "oatpp/web/protocol/http/outgoing/ResponseFactory.hpp"
namespace oatpp_authkit {
/**
* @brief Custom error handler that returns JSON error responses.
*
* Replaces oatpp's default plain-text error handler so that
* OATPP_ASSERT_HTTP errors are returned as JSON objects matching
* the StatusDto schema: {"status": "...", "code": N, "message": "..."}.
* This allows the frontend's coreFetch to parse error details reliably.
*/
class JsonErrorHandler : public oatpp::web::server::handler::ErrorHandler {
public:
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
handleError(const oatpp::web::protocol::http::Status& status,
const oatpp::String& message,
const Headers& headers) override
{
auto json = oatpp::String(
"{\"status\":\"" + std::string(status.description) +
"\",\"code\":" + std::to_string(status.code) +
",\"message\":\"" + escapeJson(message ? message->c_str() : "") + "\"}"
);
auto response = oatpp::web::protocol::http::outgoing::ResponseFactory::createResponse(
status, json
);
response->putHeader("Content-Type", "application/json");
for (const auto& pair : headers.getAll()) {
response->putHeader(pair.first.toString(), pair.second.toString());
}
return response;
}
private:
static std::string escapeJson(const char* s) {
std::string out;
for (; *s; ++s) {
switch (*s) {
case '"': out += "\\\""; break;
case '\\': out += "\\\\"; break;
case '\n': out += "\\n"; break;
case '\r': out += "\\r"; break;
case '\t': out += "\\t"; break;
default:
if (static_cast<unsigned char>(*s) < 0x20) {
char buf[8];
snprintf(buf, sizeof(buf), "\\u%04x", static_cast<unsigned char>(*s));
out += buf;
} else {
out += *s;
}
}
}
return out;
}
};
} // namespace oatpp_authkit
#endif // HANDLER_JSON_ERROR_HANDLER_HPP