mirror of
https://github.com/penpot/penpot.git
synced 2025-01-22 22:49:01 -05:00
✨ Add efficiency improvements to backend error reporting
This commit is contained in:
parent
9d05e2260c
commit
3c64955b93
7 changed files with 63 additions and 29 deletions
|
@ -88,11 +88,19 @@
|
||||||
|
|
||||||
(= code :params-validation)
|
(= code :params-validation)
|
||||||
(let [explain (::sm/explain data)
|
(let [explain (::sm/explain data)
|
||||||
payload (sm/humanize-data explain)]
|
explain (sm/humanize-data explain)]
|
||||||
{::yrs/status 400
|
{::yrs/status 400
|
||||||
::yrs/body (-> data
|
::yrs/body (-> data
|
||||||
(dissoc ::sm/explain)
|
(dissoc ::sm/explain)
|
||||||
(assoc :data payload))})
|
(assoc :explain explain))})
|
||||||
|
|
||||||
|
(= code :data-validation)
|
||||||
|
(let [explain (::sm/explain data)
|
||||||
|
explain (sm/humanize-data explain)]
|
||||||
|
{::yrs/status 400
|
||||||
|
::yrs/body (-> data
|
||||||
|
(dissoc ::sm/explain)
|
||||||
|
(assoc :explain explain))})
|
||||||
|
|
||||||
(= code :request-body-too-large)
|
(= code :request-body-too-large)
|
||||||
{::yrs/status 413 ::yrs/body data}
|
{::yrs/status 413 ::yrs/body data}
|
||||||
|
@ -114,18 +122,18 @@
|
||||||
(cond
|
(cond
|
||||||
(= code :data-validation)
|
(= code :data-validation)
|
||||||
(let [explain (::sm/explain data)
|
(let [explain (::sm/explain data)
|
||||||
payload (sm/humanize-data explain)]
|
explain (sm/humanize-data explain)]
|
||||||
(l/error :hint "data assertion error" :message (ex-message error) :cause cause)
|
(l/error :hint "data assertion error" :cause cause)
|
||||||
{::yrs/status 500
|
{::yrs/status 500
|
||||||
::yrs/body {:type :server-error
|
::yrs/body {:type :server-error
|
||||||
:code :assertion
|
:code :assertion
|
||||||
:data (-> data
|
:data (-> data
|
||||||
(dissoc ::sm/explain)
|
(dissoc ::sm/explain)
|
||||||
(assoc :data payload))}})
|
(assoc :explain explain))}})
|
||||||
|
|
||||||
(= code :spec-validation)
|
(= code :spec-validation)
|
||||||
(let [explain (ex/explain data)]
|
(let [explain (ex/explain data)]
|
||||||
(l/error :hint "spec assertion error" :message (ex-message error) :cause cause)
|
(l/error :hint "spec assertion error" :cause cause)
|
||||||
{::yrs/status 500
|
{::yrs/status 500
|
||||||
::yrs/body {:type :server-error
|
::yrs/body {:type :server-error
|
||||||
:code :assertion
|
:code :assertion
|
||||||
|
@ -135,7 +143,7 @@
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(do
|
(do
|
||||||
(l/error :hint "assertion error" :message (ex-message error) :cause cause)
|
(l/error :hint "assertion error" :cause cause)
|
||||||
{::yrs/status 500
|
{::yrs/status 500
|
||||||
::yrs/body {:type :server-error
|
::yrs/body {:type :server-error
|
||||||
:code :assertion
|
:code :assertion
|
||||||
|
@ -150,7 +158,7 @@
|
||||||
[error request parent-cause]
|
[error request parent-cause]
|
||||||
(binding [l/*context* (request->context request)]
|
(binding [l/*context* (request->context request)]
|
||||||
(let [cause (or parent-cause error)]
|
(let [cause (or parent-cause error)]
|
||||||
(l/error :hint "internal error" :message (ex-message error) :cause cause)
|
(l/error :hint "internal error" :cause cause)
|
||||||
{::yrs/status 500
|
{::yrs/status 500
|
||||||
::yrs/body {:type :server-error
|
::yrs/body {:type :server-error
|
||||||
:code :unhandled
|
:code :unhandled
|
||||||
|
@ -175,7 +183,7 @@
|
||||||
(let [state (.getSQLState ^java.sql.SQLException error)
|
(let [state (.getSQLState ^java.sql.SQLException error)
|
||||||
cause (or parent-cause error)]
|
cause (or parent-cause error)]
|
||||||
(binding [l/*context* (request->context request)]
|
(binding [l/*context* (request->context request)]
|
||||||
(l/error :hint "PSQL error" :message (ex-message error)
|
(l/error :hint "PSQL error"
|
||||||
:cause cause)
|
:cause cause)
|
||||||
(cond
|
(cond
|
||||||
(= state "57014")
|
(= state "57014")
|
||||||
|
@ -205,7 +213,7 @@
|
||||||
;; This means that exception is not a controlled exception.
|
;; This means that exception is not a controlled exception.
|
||||||
(nil? edata)
|
(nil? edata)
|
||||||
(binding [l/*context* (request->context request)]
|
(binding [l/*context* (request->context request)]
|
||||||
(l/error :hint "unexpected error" :message (ex-message error) :cause cause)
|
(l/error :hint "unexpected error" :cause cause)
|
||||||
{::yrs/status 500
|
{::yrs/status 500
|
||||||
::yrs/body {:type :server-error
|
::yrs/body {:type :server-error
|
||||||
:code :unexpected
|
:code :unexpected
|
||||||
|
@ -213,7 +221,7 @@
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(binding [l/*context* (request->context request)]
|
(binding [l/*context* (request->context request)]
|
||||||
(l/error :hint "unhandled error" :message (ex-message error) :cause cause)
|
(l/error :hint "unhandled error" :cause cause)
|
||||||
{::yrs/status 500
|
{::yrs/status 500
|
||||||
::yrs/body {:type :server-error
|
::yrs/body {:type :server-error
|
||||||
:code :unhandled
|
:code :unhandled
|
||||||
|
|
|
@ -973,7 +973,6 @@
|
||||||
:import-id id
|
:import-id id
|
||||||
:elapsed (dt/format-duration (tp))
|
:elapsed (dt/format-duration (tp))
|
||||||
:error? (some? @cs)
|
:error? (some? @cs)
|
||||||
:cause @cs
|
|
||||||
)))))
|
)))))
|
||||||
|
|
||||||
;; --- Command: export-binfile
|
;; --- Command: export-binfile
|
||||||
|
|
|
@ -66,9 +66,9 @@
|
||||||
|
|
||||||
(defn explain
|
(defn explain
|
||||||
([data] (explain data nil))
|
([data] (explain data nil))
|
||||||
([data {:keys [level length] :or {level 8 length 10} :as opts}]
|
([data {:keys [level length] :or {level 8 length 12} :as opts}]
|
||||||
(cond
|
(cond
|
||||||
;; ;; NOTE: a special case for spec validation errors on integrant
|
;; NOTE: a special case for spec validation errors on integrant
|
||||||
(and (= (:reason data) :integrant.core/build-failed-spec)
|
(and (= (:reason data) :integrant.core/build-failed-spec)
|
||||||
(contains? data :explain))
|
(contains? data :explain))
|
||||||
(explain (:explain data) opts)
|
(explain (:explain data) opts)
|
||||||
|
@ -81,8 +81,7 @@
|
||||||
(s/explain-out (update data ::s/problems #(take length %)))))
|
(s/explain-out (update data ::s/problems #(take length %)))))
|
||||||
|
|
||||||
(contains? data ::sm/explain)
|
(contains? data ::sm/explain)
|
||||||
(-> (sm/humanize-data (::sm/explain data))
|
(sm/humanize-data (::sm/explain data) :level level :length length))))
|
||||||
(pp/pprint-str {:level level :length length})))))
|
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(defn format-throwable
|
(defn format-throwable
|
||||||
|
|
|
@ -271,7 +271,7 @@
|
||||||
(js/console.error n (pr-str v))
|
(js/console.error n (pr-str v))
|
||||||
(js/console.error n v))))
|
(js/console.error n v))))
|
||||||
|
|
||||||
(when cause
|
(when (ex/exception? cause)
|
||||||
(let [data (ex-data cause)
|
(let [data (ex-data cause)
|
||||||
explain (ex/explain data)]
|
explain (ex/explain data)]
|
||||||
(when explain
|
(when explain
|
||||||
|
|
|
@ -8,7 +8,9 @@
|
||||||
(:refer-clojure :exclude [deref merge parse-uuid])
|
(:refer-clojure :exclude [deref merge parse-uuid])
|
||||||
#?(:cljs (:require-macros [app.common.schema :refer [ignoring]]))
|
#?(:cljs (:require-macros [app.common.schema :refer [ignoring]]))
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.pprint :as pp]
|
||||||
[app.common.schema.generators :as sg]
|
[app.common.schema.generators :as sg]
|
||||||
[app.common.schema.openapi :as-alias oapi]
|
[app.common.schema.openapi :as-alias oapi]
|
||||||
[app.common.schema.registry :as sr]
|
[app.common.schema.registry :as sr]
|
||||||
|
@ -142,10 +144,19 @@
|
||||||
(m/decoder s options transformer)))
|
(m/decoder s options transformer)))
|
||||||
|
|
||||||
(defn humanize-data
|
(defn humanize-data
|
||||||
[explain-data]
|
[{:keys [schema errors value]} & {:keys [length level]}]
|
||||||
(-> explain-data
|
(let [errors (mapv #(update % :schema form) errors)]
|
||||||
(update :schema form)
|
(with-out-str
|
||||||
(update :errors (fn [errors] (map #(update % :schema form) errors)))))
|
(println "Schema: ")
|
||||||
|
(println (pp/pprint-str (form schema)) {:level (d/nilv level 10)
|
||||||
|
:length (d/nilv length 10)})
|
||||||
|
(println)
|
||||||
|
(println "Errors:")
|
||||||
|
(println (pp/pprint-str errors {:level (d/nilv level 10)
|
||||||
|
:length (d/nilv length 10)}))
|
||||||
|
(println "Value:")
|
||||||
|
(println (pp/pprint-str value {:level (d/nilv level 5)
|
||||||
|
:length (d/nilv length 10)})))))
|
||||||
|
|
||||||
(defn pretty-explain
|
(defn pretty-explain
|
||||||
[s d]
|
[s d]
|
||||||
|
@ -191,7 +202,7 @@
|
||||||
(fn [v]
|
(fn [v]
|
||||||
(let [result (v-fn v)]
|
(let [result (v-fn v)]
|
||||||
(when (and (not result) (true? dm/*assert-context*))
|
(when (and (not result) (true? dm/*assert-context*))
|
||||||
(let [hint (str "schema assert: " (pr-str (form s)))
|
(let [hint "schema validation"
|
||||||
exp (e-fn v)]
|
exp (e-fn v)]
|
||||||
(throw (ex-info hint {:type :assertion
|
(throw (ex-info hint {:type :assertion
|
||||||
:code :data-validation
|
:code :data-validation
|
||||||
|
@ -204,7 +215,7 @@
|
||||||
[s v]
|
[s v]
|
||||||
(let [result (validate s v)]
|
(let [result (validate s v)]
|
||||||
(when (and (not result) (true? dm/*assert-context*))
|
(when (and (not result) (true? dm/*assert-context*))
|
||||||
(let [hint (str "schema assert: " (pr-str (form s)))
|
(let [hint "schema validation"
|
||||||
exp (explain s v)]
|
exp (explain s v)]
|
||||||
(throw (ex-info hint {:type :assertion
|
(throw (ex-info hint {:type :assertion
|
||||||
:code :data-validation
|
:code :data-validation
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
[data]
|
[data]
|
||||||
(-> data
|
(-> data
|
||||||
(dissoc ::sm/explain)
|
(dissoc ::sm/explain)
|
||||||
(dissoc :hint)
|
(dissoc :explain)
|
||||||
(dissoc ::trace)
|
(dissoc ::trace)
|
||||||
(dissoc ::instance)
|
(dissoc ::instance)
|
||||||
(pp/pprint {:width 70})))
|
(pp/pprint {:width 70})))
|
||||||
|
@ -33,8 +33,9 @@
|
||||||
(defn- print-explain!
|
(defn- print-explain!
|
||||||
[data]
|
[data]
|
||||||
(when-let [explain (::sm/explain data)]
|
(when-let [explain (::sm/explain data)]
|
||||||
(-> (sm/humanize-data explain)
|
(js/console.log (sm/humanize-data explain)))
|
||||||
(pp/pprint {:width 70}))))
|
(when-let [explain (:explain data)]
|
||||||
|
(js/console.log explain)))
|
||||||
|
|
||||||
(defn- print-trace!
|
(defn- print-trace!
|
||||||
[data]
|
[data]
|
||||||
|
@ -98,7 +99,8 @@
|
||||||
|
|
||||||
(print-group! "Validation Error"
|
(print-group! "Validation Error"
|
||||||
(fn []
|
(fn []
|
||||||
(print-data! error))))
|
(print-data! error)
|
||||||
|
(print-explain! error))))
|
||||||
|
|
||||||
|
|
||||||
;; This is a pure frontend error that can be caused by an active
|
;; This is a pure frontend error that can be caused by an active
|
||||||
|
@ -223,7 +225,22 @@
|
||||||
|
|
||||||
(print-group! "Server Error"
|
(print-group! "Server Error"
|
||||||
(fn []
|
(fn []
|
||||||
(print-data! error))))
|
(print-data! (dissoc error :data))
|
||||||
|
|
||||||
|
(when-let [werror (:data error)]
|
||||||
|
(cond
|
||||||
|
(= :assertion (:type werror))
|
||||||
|
(print-group! "Assertion Error"
|
||||||
|
(fn []
|
||||||
|
(print-data! werror)
|
||||||
|
(print-explain! werror)))
|
||||||
|
|
||||||
|
:else
|
||||||
|
(print-group! "Unexpected"
|
||||||
|
(fn []
|
||||||
|
(print-data! werror)
|
||||||
|
(print-explain! werror))))))))
|
||||||
|
|
||||||
|
|
||||||
(defonce uncaught-error-handler
|
(defonce uncaught-error-handler
|
||||||
(letfn [(is-ignorable-exception? [cause]
|
(letfn [(is-ignorable-exception? [cause]
|
||||||
|
|
|
@ -258,9 +258,9 @@
|
||||||
{:cmd :analyze-import
|
{:cmd :analyze-import
|
||||||
:files files})
|
:files files})
|
||||||
(rx/delay-emit emit-delay)
|
(rx/delay-emit emit-delay)
|
||||||
|
(rx/filter some?)
|
||||||
(rx/subs
|
(rx/subs
|
||||||
(fn [{:keys [uri data error type] :as msg}]
|
(fn [{:keys [uri data error type] :as msg}]
|
||||||
(log/debug :uri uri :data data :error error)
|
|
||||||
(if (some? error)
|
(if (some? error)
|
||||||
(swap! state update :files set-analyze-error uri)
|
(swap! state update :files set-analyze-error uri)
|
||||||
(swap! state update :files set-analyze-result uri type data)))))))
|
(swap! state update :files set-analyze-result uri type data)))))))
|
||||||
|
|
Loading…
Add table
Reference in a new issue