;; lib/dream/error.sx — Dream-on-SX status phrases + error-handling middleware.
;; dream-catch wraps a handler and turns a raised error into a 500 response (or a
;; custom page). Depends on types.sx.

;; ── status reason phrases ──────────────────────────────────────────
(define dr/status-texts {:206 "Partial Content" :202 "Accepted" :422 "Unprocessable Entity" :400 "Bad Request" :302 "Found" :204 "No Content" :502 "Bad Gateway" :429 "Too Many Requests" :301 "Moved Permanently" :415 "Unsupported Media Type" :405 "Method Not Allowed" :303 "See Other" :401 "Unauthorized" :304 "Not Modified" :503 "Service Unavailable" :404 "Not Found" :308 "Permanent Redirect" :504 "Gateway Timeout" :416 "Range Not Satisfiable" :500 "Internal Server Error" :307 "Temporary Redirect" :201 "Created" :501 "Not Implemented" :409 "Conflict" :200 "OK" :410 "Gone" :403 "Forbidden"})

(define
  dream-status-text
  (fn (status) (or (get dr/status-texts (str status)) "Unknown")))
(define
  dream-status-line
  (fn (status) (str status " " (dream-status-text status))))

;; ── error-handling middleware ──────────────────────────────────────
(define
  dream-default-error-page
  (fn
    (req e)
    (dream-html-status
      500
      (str "<h1>" (dream-status-line 500) "</h1>"))))

(define
  dream-catch-with
  (fn
    (on-error)
    (fn
      (next)
      (fn (req) (guard (e (true (on-error req e))) (next req))))))

(define dream-catch (dream-catch-with dream-default-error-page))

;; a fallback handler that renders a status page for any code
(define
  dream-status-page
  (fn
    (status)
    (dream-html-status
      status
      (str "<h1>" (dream-status-line status) "</h1>"))))
