reitit 2025-03-17

I wrote a custom safe-response-middleware (see code below) to replace coerce-response-middleware. It validates responses against the Reitit schema, logs errors, and returns the original response instead of a Reitit error response.

(defn safe-response-middleware
  "Middleware that tries to coerce the response but logs and returns
   the original data if mismatch occurs."
  [handler]
  (fn [request]
    (let [response (handler request)
          status (or (:status response) 200)
          route (:reitit.core/match request)
          route-data (:data route)
          method-key (keyword (-> request
                                  :request-method
                                  name))
          method-data (get route-data method-key)
          route-responses (:responses method-data)

          response-schema (get-in route-responses [status :body])]

      (if (nil? response-schema)
        response
        (try
          (let [coercers (coercion/response-coercers
                           rcm/coercion
                           {status {:body response-schema}}
                           {})]
            (coercion/coerce-response coercers request response))
          (catch Exception e
            (let [data (ex-data e)
                  encoded-error (coercion/encode-error data)
                  humanized (:humanized encoded-error)]
              (log/error-with-stacktrace e "Reitit response schema validation failed " humanized)
              (if (utils/in-prod?)
                response
                {:status 200 :body humanized}))))))))
I’m wondering if there is a built-in way in Reitit (or its coercion library) to automatically remove invalid parts of a response instead of failing validation entirely.