LCOV - code coverage report
Current view: top level - http/server - error_format.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 94.4 % 18 17
Test Date: 2026-11-10 10:38:07 Functions: 100.0 % 2 2

            Line data    Source code
       1              : #ifndef THINGER_HTTP_SERVER_ERROR_FORMAT_HPP
       2              : #define THINGER_HTTP_SERVER_ERROR_FORMAT_HPP
       3              : 
       4              : #include "../common/http_response.hpp"
       5              : #include "../../util/logger.hpp"
       6              : #include "../../util/types.hpp"
       7              : #include <nlohmann/json.hpp>
       8              : #include <functional>
       9              : #include <string>
      10              : 
      11              : namespace thinger::http {
      12              : 
      13              : // Error answered with response::error(), or generated by the server itself (invalid JSON
      14              : // body, schema validation, 404/405, 413, 500...)
      15              : struct http_error {
      16              :     http_response::status status;
      17              : 
      18              :     // Error message, empty if none was given (http_response::get_reason_phrase(status)
      19              :     // gives a generic one)
      20              :     std::string message;
      21              : 
      22              :     // Additional data, null if none; e.g. {"context": ["<root>", "[name]"]} for schema
      23              :     // validation errors (the location of the invalid value)
      24              :     nlohmann::json details;
      25              : };
      26              : 
      27              : // Writes the body of an error response (content, content type and any extra header);
      28              : // the status is already set
      29              : using error_formatter = sync_callback<void(const http_error& error, http_response& response)>;
      30              : 
      31              : // Default format: the message as text/plain, or, for errors with details, the JSON object
      32              : // {"error": {"message": <message>, <details>...}}
      33         3152 : inline void default_error_formatter(const http_error& error, http_response& response) {
      34         3152 :     if (error.details.is_null()) {
      35         3052 :         response.set_content(error.message, "text/plain");
      36         3052 :         return;
      37              :     }
      38          900 :     nlohmann::json body = {{"error", {{"message", error.message}}}};
      39          100 :     if (error.details.is_object()) {
      40          100 :         body["error"].update(error.details);
      41              :     } else {
      42            0 :         body["error"]["details"] = error.details;
      43              :     }
      44          100 :     response.set_content(body.dump(), "application/json");
      45         1000 : }
      46              : 
      47              : // Format an error with `formatter`, or in the default format if there is none (or it fails)
      48         3302 : inline void format_error(const error_formatter* formatter, const http_error& error, http_response& response) {
      49         3302 :     if (formatter && *formatter) {
      50              :         try {
      51          153 :             (*formatter)(error, response);
      52          150 :             return;
      53            3 :         } catch (const std::exception& e) {
      54            3 :             LOG_ERROR("Error formatter failed: {}", e.what());
      55            3 :         }
      56              :     }
      57         3152 :     default_error_formatter(error, response);
      58              : }
      59              : 
      60              : } // namespace thinger::http
      61              : 
      62              : #endif // THINGER_HTTP_SERVER_ERROR_FORMAT_HPP
        

Generated by: LCOV version 2.0-1