0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-13 02:28:18 -05:00

Many improvements on error reporting.

This commit is contained in:
Andrey Antukh 2020-12-21 09:46:27 +01:00 committed by Alonso Torres
parent 0f37c8ecbd
commit b7353db14e
5 changed files with 99 additions and 88 deletions

View file

@ -45,7 +45,8 @@
:allow-demo-users true
:registration-enabled true
:registration-domain-whitelist ""
:debug-humanize-transit true
:debug true
;; This is the time should transcurr after the last page
;; modification in order to make the file ellegible for
@ -95,7 +96,7 @@
(s/def ::allow-demo-users ::us/boolean)
(s/def ::registration-enabled ::us/boolean)
(s/def ::registration-domain-whitelist ::us/string)
(s/def ::debug-humanize-transit ::us/boolean)
(s/def ::debug ::us/boolean)
(s/def ::public-uri ::us/string)
(s/def ::backend-uri ::us/string)
@ -153,7 +154,7 @@
::smtp-ssl
::host
::file-trimming-threshold
::debug-humanize-transit
::debug
::allow-demo-users
::registration-enabled
::registration-domain-whitelist

View file

@ -15,6 +15,17 @@
[cuerdas.core :as str]
[expound.alpha :as expound]))
(defn get-context-string
[err request]
(str
"=| uri: " (pr-str (:uri request)) "\n"
"=| method: " (pr-str (:request-method request)) "\n"
"=| params: " (pr-str (:params request)) "\n"
(when (ex/ex-info? err)
(str "=| ex-data: " (pr-str (ex-data err)) "\n"))
"\n"))
(defmulti handle-exception
(fn [err & _rest]
(let [edata (ex-data err)]
@ -29,18 +40,32 @@
(defmethod handle-exception :validation
[err req]
(let [header (get-in req [:headers "accept"])
error (ex-data err)]
edata (ex-data err)]
(cond
(and (str/starts-with? header "text/html")
(= :spec-validation (:code error)))
{:status 400
:headers {"content-type" "text/html"}
:body (str "<pre style='font-size:16px'>"
(:hint-verbose error)
"</pre>\n")}
(= :spec-validation (:code edata))
(if (str/starts-with? header "text/html")
{:status 400
:headers {"content-type" "text/html"}
:body (str "<pre style='font-size:16px'>"
(with-out-str
(expound/printer (:data edata)))
"</pre>\n")}
{:status 400
:body (assoc edata :explain (with-out-str (expound/printer (:data edata))))})
:else
{:status 400
:body error})))
:body edata})))
(defmethod handle-exception :assertion
[error request]
(let [edata (ex-data error)]
(log/errorf error
(str "Assertion error\n"
(get-context-string request edata)
(with-out-str (expound/printer (:data edata)))))
{:status 500
:body (assoc edata :explain (with-out-str (expound/printer (:data edata))))}))
(defmethod handle-exception :not-found
[err _]
@ -52,48 +77,16 @@
[err req]
(handle-exception (.getCause ^Throwable err) req))
(defmethod handle-exception :parse
[err _]
{:status 400
: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 request]
(log/errorf err (str "Internal Error\n" (get-context-string err request)))
{:status 500
:body {:type :internal-error
:message (ex-message err)
:data (ex-data err)}})
[error request]
(let [edata (ex-data error)]
(log/errorf error
(str "Internal Error\n"
(get-context-string request edata)))
{:status 500
:body (dissoc edata :data)}))
(defn handle
[error req]

View file

@ -13,6 +13,8 @@
[app.config :as cfg]
[app.metrics :as mtx]
[app.util.transit :as t]
[clojure.data.json :as json]
[clojure.java.io :as io]
[ring.middleware.cookies :refer [wrap-cookies]]
[ring.middleware.keyword-params :refer [wrap-keyword-params]]
[ring.middleware.multipart-params :refer [wrap-multipart-params]]
@ -21,20 +23,42 @@
(defn- wrap-parse-request-body
[handler]
(letfn [(parse-body [body]
(letfn [(parse-transit [body]
(let [reader (t/reader body)]
(t/read! reader)))
(parse-json [body]
(let [reader (io/reader body)]
(json/read reader)))
(parse [type body]
(try
(let [reader (t/reader body)]
(t/read! reader))
(case type
:json (parse-json body)
:transit (parse-transit body))
(catch Exception e
(ex/raise :type :parse
:message "Unable to parse transit from request body."
:cause e))))]
(let [type (if (:debug cfg/config) :json-verbose :json)
data {:type :parse
:hint "Unable to parse request body"
:message (ex-message e)}]
{:status 400
:body (t/encode-str data {:type type})}))))]
(fn [{:keys [headers body request-method] :as request}]
(handler
(cond-> request
(and (= "application/transit+json" (get headers "content-type"))
(not= request-method :get))
(assoc :body-params (parse-body body)))))))
(let [ctype (get headers "content-type")]
(handler
(case ctype
"application/transit+json"
(let [params (parse :transit body)]
(-> request
(assoc :body-params params)
(update :params merge params)))
"application/json"
(let [params (parse :json body)]
(-> request
(assoc :body-params params)
(update :params merge params)))
request))))))
(def parse-request-body
{:name ::parse-request-body
@ -43,9 +67,7 @@
(defn- impl-format-response-body
[response]
(let [body (:body response)
type (if (:debug-humanize-transit cfg/config)
:json-verbose
:json)]
type (if (:debug cfg/config) :json-verbose :json)]
(cond
(coll? body)
(-> response

View file

@ -135,24 +135,18 @@
;; --- Macros
(defn spec-assert
[spec x message]
(if (s/valid? spec x)
x
(ex/raise :type :assertion
:data (s/explain-data spec x)
:message message
#?@(:cljs [:stack (.-stack (ex-info message {}))]))))
(defn spec-assert*
[spec x message context]
(if (s/valid? spec x)
x
(ex/raise :type :assertion
:data (s/explain-data spec x)
:context context
:message message
#?@(:cljs [:stack (.-stack (ex-info message {}))]))))
(let [data (s/explain-data spec x)
hint (with-out-str (s/explain-out data))]
(ex/raise :type :assertion
:data data
:hint hint
:context context
:message message
#?@(:cljs [:stack (.-stack (ex-info message {}))])))))
(defmacro assert
@ -186,16 +180,13 @@
[spec data]
(let [result (s/conform spec data)]
(when (= result ::s/invalid)
(let [edata (s/explain-data spec data)
nhint (with-out-str
(s/explain-out edata))
vhint (with-out-str
(expound/printer edata))]
(let [data (s/explain-data spec data)
hint (with-out-str
(s/explain-out data))]
(throw (ex/error :type :validation
:code :spec-validation
:data data
:hint nhint
:hint-verbose vhint))))
:hint hint))))
result))
(defmacro instrument!

View file

@ -242,11 +242,15 @@
(st/emit! (rt/nav :login))
(ts/schedule
(st/emitf (dm/show {:content "Not authorized to see this content."
:timeout 5000
:timeout 3000
:type :error}))))
(defmethod ptk/handle-error :assertion
[{:keys [data stack message context] :as error}]
(ts/schedule
(st/emitf (dm/show {:content "Internal assertion error."
:type :error
:timeout 2000})))
(js/console.group message)
(js/console.info (str/format "ns: '%s'\nname: '%s'\nfile: '%s:%s'"
(:ns context)