🎉 Add better error reporting.

This commit is contained in:
Andrey Antukh 2020-12-04 20:38:38 +01:00 committed by Alonso Torres
parent a881d86637
commit 4d7a34a998
14 changed files with 238 additions and 72 deletions

View file

@ -10,13 +10,16 @@
(ns app.http.errors
"A errors handling for the http server."
(:require
[app.common.exceptions :as ex]
[clojure.tools.logging :as log]
[cuerdas.core :as str]))
[cuerdas.core :as str]
[expound.alpha :as expound]))
(defmulti handle-exception
(fn [err & _rest]
(:type (ex-data err))))
(let [edata (ex-data err)]
(or (:type edata)
(class err)))))
(defmethod handle-exception :authorization
[err _]
@ -26,17 +29,19 @@
(defmethod handle-exception :validation
[err req]
(let [header (get-in req [:headers "accept"])
response (ex-data err)]
edata (ex-data err)]
(cond
(and (str/starts-with? header "text/html")
(= :spec-validation (:code response)))
(= :spec-validation (:code edata)))
{:status 400
:headers {"content-type" "text/html"}
:body (str "<pre style='font-size:16px'>" (:explain response) "</pre>\n")}
:body (str "<pre style='font-size:16px'>"
(with-out-str
(:data edata))
"</pre>\n")}
:else
{:status 400
:body response})))
:body edata})))
(defmethod handle-exception :ratelimit
[_ _]
@ -60,11 +65,38 @@
:body {:type :parse
:message (ex-message err)}})
(defn get-context-string
[err request]
(str
"=| uri: " (pr-str (:uri request)) "\n"
"=| method: " (pr-str (:request-method request)) "\n"
"=| path-params: " (pr-str (:path-params request)) "\n"
"=| query-params: " (pr-str (:query-params request)) "\n"
(when-let [bparams (:body-params request)]
(str "=| body-params: " (pr-str bparams) "\n"))
(when (ex/ex-info? err)
(str "=| ex-data: " (pr-str (ex-data err)) "\n"))
"\n"))
(defmethod handle-exception :assertion
[err request]
(let [{:keys [data] :as edata} (ex-data err)]
(log/errorf err
(str "Assertion error\n"
(get-context-string err request)
(with-out-str (expound/printer data))))
{:status 500
:body {:type :internal-error
:message "Assertion error"
:data (ex-data err)}}))
(defmethod handle-exception :default
[err req]
(log/error "Unhandled exception on request:" (:path req) "\n"
(with-out-str
(.printStackTrace ^Throwable err (java.io.PrintWriter. *out*))))
[err request]
(log/errorf err (str "Internal Error\n" (get-context-string err request)))
{:status 500
:body {:type :internal-error
:message (ex-message err)