-
-
Save borkdude/441379ec59d8da7f72348453ee15f32a to your computer and use it in GitHub Desktop.
Yada error handling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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. | |
;; https://clojurians.slack.com/archives/C0702A7SB/p1493735777665719 | |
;; But this also works. Maybe if we get into more issues, we'll try our own error interceptor chain. | |
;; See https://github.com/juxt/yada/blob/5d49342bcb994309b96673fb4a531ff313647c79/src/yada/handler.clj#L52 | |
(intern 'yada.handler 'error-representations | |
(ys/representation-seq | |
(ys/representation-set-coercer | |
[{:media-type #{"application/json" | |
"application/transit+json" | |
"application/json;pretty=true;q=0.96" | |
"text/plain;q=0.9" | |
"text/html;q=0.8" | |
"application/edn;q=0.6" | |
"application/edn;pretty=true;q=0.5"} | |
:charset charset/platform-charsets}]))) | |
... | |
(defn define-error-renderers [dev-env?] | |
;; See https://github.com/juxt/yada/blob/master/src/yada/body.clj#L214 | |
(defmethod render-error "text/html" | |
[status ^Throwable error representation {:keys [id options] :as m}] | |
(parser/render-file | |
"error.html" | |
{:status status | |
:message (format "%d: %s" status (body/get-error-message status)) | |
:description (body/get-error-description status) | |
:exception (when dev-env? | |
(let [baos (java.io.ByteArrayOutputStream.) | |
pw (java.io.PrintWriter. | |
(java.io.OutputStreamWriter. 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) | |
error-response | |
(if-let [message (get error-messages exception-type)] | |
(error/error message error) | |
(case exception-type | |
... | |
exception-data | |
;; Fallback | |
(do | |
(when exception-type | |
(warn "Uncaught exception-type" exception-type)) | |
(error/error error)))) | |
error-response | |
(if-not dev-env? | |
(dissoc error-response :details) | |
error-response) | |
response (not-empty | |
(nn-hash-map :error (not-empty error-response)))] | |
response))) | |
(info "Responding with" status "on request" | |
(select-keys request [:uri :params])))) | |
;; See https://github.com/juxt/yada/blob/master/src/yada/body.clj#L252 | |
(defmethod render-error "application/json" | |
[status error representation ctx] | |
(api-error-renderer status error representation ctx)) | |
;; See https://github.com/juxt/yada/blob/master/src/yada/body.clj#L261 | |
(defmethod render-error "application/transit+json" | |
[status error representation ctx] | |
(api-error-renderer status error representation ctx))) | |
;;;; Scratch | |
(comment | |
(rr/reset) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment