Skip to content

Instantly share code, notes, and snippets.

Created Jan 17, 2019
What would you like to do?
Yada error handling
(ns app.yada.error-renderers
"Yada error renderer overrides"
{:authors ["Michiel Borkent"]}
(:require ...
[reloaded.repl :as rr]
[selmer.parser :as parser]
[taoensso.timbre :refer [debug info error warn]]
[yada.body :as body :refer [render-error get-error-message]]
[yada.charset :as charset]
[yada.handler :as handler] ;; load because of interning
[yada.schema :as ys :refer [resource-coercer]]))
;; Note: @malcolmsparks recommended the following for adding application/json error handling
;; > For now, you can replace with your own error interceptor chain
;; > It is a bit arduous but worthwhile because you're then in complete control of error handling.
;; But this also works. Maybe if we get into more issues, we'll try our own error interceptor chain.
;; See
(intern 'yada.handler 'error-representations
[{:media-type #{"application/json"
:charset charset/platform-charsets}])))
(defn define-error-renderers [dev-env?]
;; See
(defmethod render-error "text/html"
[status ^Throwable error representation {:keys [id options] :as m}]
{:status status
:message (format "%d: %s" status (body/get-error-message status))
:description (body/get-error-description status)
:exception (when dev-env?
(let [baos (
pw (
( baos))]
(.printStackTrace error pw)
(.flush pw)
(String. (.toByteArray baos))))}))
(defn api-error-renderer [status error representation
{:keys [id options method request]}]
(if error ;; no error is provided with 404, etc.
(let [error (unnest-exception error)]
(or (and (= 400 status)
(let [maybe-error (:error (ex-data error))
maybe-error (when (map? maybe-error)
(not-empty maybe-error))]
(and maybe-error
{:error maybe-error
:message "Schema validation error"})))
(let [exception-data (ex-data error)
exception-type (:type exception-data)
(if-let [message (get error-messages exception-type)]
(error/error message error)
(case exception-type
;; Fallback
(when exception-type
(warn "Uncaught exception-type" exception-type))
(error/error error))))
(if-not dev-env?
(dissoc error-response :details)
response (not-empty
(nn-hash-map :error (not-empty error-response)))]
(info "Responding with" status "on request"
(select-keys request [:uri :params]))))
;; See
(defmethod render-error "application/json"
[status error representation ctx]
(api-error-renderer status error representation ctx))
;; See
(defmethod render-error "application/transit+json"
[status error representation ctx]
(api-error-renderer status error representation ctx)))
;;;; Scratch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment