Improve error reporting

This commit is contained in:
Andrey Antukh 2023-11-20 19:25:09 +01:00
parent acb17b0552
commit 0081db4770
3 changed files with 42 additions and 31 deletions

View file

@ -121,15 +121,14 @@
cause (or parent-cause error)] cause (or parent-cause error)]
(cond (cond
(= code :data-validation) (= code :data-validation)
(let [explain (::sm/explain data) (let [explain (ex/explain data)]
explain (sm/humanize-data explain)]
(l/error :hint "data assertion 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 :explain explain))}}) (cond-> explain (assoc :explain explain)))}})
(= code :spec-validation) (= code :spec-validation)
(let [explain (ex/explain data)] (let [explain (ex/explain data)]
@ -231,7 +230,7 @@
(defmethod handle-exception java.util.concurrent.CompletionException (defmethod handle-exception java.util.concurrent.CompletionException
[cause request _] [cause request _]
(let [cause' (ex-cause cause)] (let [cause' (ex-cause cause)]
(if (ex/error? cause) (if (ex/error? cause')
(handle-error cause' request cause) (handle-error cause' request cause)
(handle-exception cause' request cause)))) (handle-exception cause' request cause))))

View file

@ -40,32 +40,40 @@
[{:keys [::l/context ::l/message ::l/props ::l/logger ::l/level ::l/cause] :as record}] [{:keys [::l/context ::l/message ::l/props ::l/logger ::l/level ::l/cause] :as record}]
(us/assert! ::l/record record) (us/assert! ::l/record record)
(let [data (ex-data cause) (if (or (instance? java.util.concurrent.CompletionException cause)
ctx (-> context (instance? java.util.concurrent.ExecutionException cause))
(assoc :tenant (cf/get :tenant)) (-> record
(assoc :host (cf/get :host)) (assoc ::trace (ex/format-throwable cause :data? false :explain? false :header? false :summary? false))
(assoc :public-uri (cf/get :public-uri)) (assoc ::l/cause (ex-cause cause))
(assoc :logger/name logger) (record->report))
(assoc :logger/level level)
(dissoc :request/params :value :params :data))]
(merge
{:context (-> (into (sorted-map) ctx)
(pp/pprint-str :width 200 :length 50 :level 10))
:props (pp/pprint-str props :width 200 :length 50)
:hint (or (ex-message cause) @message)
:trace (ex/format-throwable cause :data? false :explain? false :header? false :summary? false)}
(when-let [params (or (:request/params context) (:params context))] (let [data (ex-data cause)
{:params (pp/pprint-str params :width 200 :length 50 :level 10)}) ctx (-> context
(assoc :tenant (cf/get :tenant))
(assoc :host (cf/get :host))
(assoc :public-uri (cf/get :public-uri))
(assoc :logger/name logger)
(assoc :logger/level level)
(dissoc :request/params :value :params :data))]
(merge
{:context (-> (into (sorted-map) ctx)
(pp/pprint-str :width 200 :length 50 :level 10))
:props (pp/pprint-str props :width 200 :length 50)
:hint (or (ex-message cause) @message)
:trace (or (::trace record)
(ex/format-throwable cause :data? false :explain? false :header? false :summary? false))}
(when-let [value (:value context)] (when-let [params (or (:request/params context) (:params context))]
{:value (pp/pprint-str value :width 200 :length 50 :level 10)}) {:params (pp/pprint-str params :width 200 :length 50 :level 10)})
(when-let [data (some-> data (dissoc ::s/problems ::s/value ::s/spec ::sm/explain :hint))] (when-let [value (:value context)]
{:data (pp/pprint-str data :width 200)}) {:value (pp/pprint-str value :width 200 :length 50 :level 10)})
(when-let [explain (ex/explain data {:level 10 :length 50})] (when-let [data (some-> data (dissoc ::s/problems ::s/value ::s/spec ::sm/explain :hint))]
{:explain explain})))) {:data (pp/pprint-str data :width 200)})
(when-let [explain (ex/explain data {:level 10 :length 50})]
{:explain explain})))))
(defn error-record? (defn error-record?
[{:keys [::l/level ::l/cause]}] [{:keys [::l/level ::l/cause]}]

View file

@ -66,7 +66,7 @@
(defn explain (defn explain
([data] (explain data nil)) ([data] (explain data nil))
([data {:keys [level length] :or {level 8 length 12} :as opts}] ([data 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)
@ -78,10 +78,10 @@
(contains? data ::s/spec)) (contains? data ::s/spec))
(binding [s/*explain-out* expound/printer] (binding [s/*explain-out* expound/printer]
(with-out-str (with-out-str
(s/explain-out (update data ::s/problems #(take length %))))) (s/explain-out (update data ::s/problems #(take (:length opts 10) %)))))
(contains? data ::sm/explain) (contains? data ::sm/explain)
(sm/humanize-data (::sm/explain data) :level level :length length)))) (sm/humanize-data (::sm/explain data) opts))))
#?(:clj #?(:clj
(defn format-throwable (defn format-throwable
@ -93,7 +93,7 @@
explain? true explain? true
chain? true chain? true
data-length 10 data-length 10
data-level 8}}] data-level 5}}]
(letfn [(print-trace-element [^StackTraceElement e] (letfn [(print-trace-element [^StackTraceElement e]
(let [class (.getClassName e) (let [class (.getClassName e)
@ -123,7 +123,11 @@
(print-trace-title [^Throwable cause] (print-trace-title [^Throwable cause]
(print " → ") (print " → ")
(printf "%s: %s" (.getName (class cause)) (first (str/lines (ex-message cause)))) (printf "%s: %s" (.getName (class cause))
(-> (ex-message cause)
(str/lines)
(first)
(str/prune 100)))
(when-let [^StackTraceElement e (first (.getStackTrace ^Throwable cause))] (when-let [^StackTraceElement e (first (.getStackTrace ^Throwable cause))]
(printf " (%s:%d)" (or (.getFileName e) "") (.getLineNumber e))) (printf " (%s:%d)" (or (.getFileName e) "") (.getLineNumber e)))