Skip to content

Commit

Permalink
better errors
Browse files Browse the repository at this point in the history
  • Loading branch information
ikitommi committed Dec 31, 2023
1 parent f2e946e commit b554920
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 28 deletions.
14 changes: 7 additions & 7 deletions src/malli/dev/pretty.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@
;; formatters
;;

(defmethod v/-format ::m/explain [_ _ {:keys [schema] :as explanation} printer]
(defmethod v/-format ::m/explain [_ {:keys [schema] :as explanation} printer]
{:body
[:group
(v/-block "Value:" (v/-visit (me/error-value explanation printer) printer) printer) :break :break
(v/-block "Errors:" (v/-visit (me/humanize explanation) printer) printer) :break :break
(v/-block "Schema:" (v/-visit schema printer) printer) :break :break
(v/-block "More information:" (v/-link "https://cljdoc.org/d/metosin/malli/CURRENT" printer) printer)]})

(defmethod v/-format ::m/invalid-input [_ _ {:keys [args input fn-name]} printer]
(defmethod v/-format ::m/invalid-input [_ {:keys [args input fn-name]} printer]
{:body
[:group
(v/-block "Invalid function arguments:" (v/-visit args printer) printer) :break :break
Expand All @@ -43,7 +43,7 @@
(v/-block "Errors:" (-explain input args printer) printer) :break :break
(v/-block "More information:" (v/-link "https://cljdoc.org/d/metosin/malli/CURRENT/doc/function-schemas" printer) printer)]})

(defmethod v/-format ::m/invalid-output [_ _ {:keys [value args output fn-name]} printer]
(defmethod v/-format ::m/invalid-output [_ {:keys [value args output fn-name]} printer]
{:body
[:group
(v/-block "Invalid function return value:" (v/-visit value printer) printer) :break :break
Expand All @@ -53,15 +53,15 @@
(v/-block "Errors:" (-explain output value printer) printer) :break :break
(v/-block "More information:" (v/-link "https://cljdoc.org/d/metosin/malli/CURRENT/doc/function-schemas" printer) printer)]})

(defmethod v/-format ::m/invalid-arity [_ _ {:keys [args arity schema fn-name]} printer]
(defmethod v/-format ::m/invalid-arity [_ {:keys [args arity schema fn-name]} printer]
{:body
[:group
(v/-block (str "Invalid function arity (" arity "):") (v/-visit args printer) printer) :break :break
(v/-block "Function Schema:" (v/-visit schema printer) printer) :break :break
#?(:cljs (v/-block "Function Var:" (v/-visit fn-name printer) printer)) :break :break
(v/-block "More information:" (v/-link "https://cljdoc.org/d/metosin/malli/CURRENT/doc/function-schemas" printer) printer)]})

(defmethod v/-format ::m/invalid-schema [_ _ {:keys [schema form]} printer]
(defmethod v/-format ::m/invalid-schema [_ {:keys [schema form]} printer]
(let [proposals (seq (me/-most-similar-to #{schema} schema (set (keys (mr/schemas m/default-registry)))))]
{:body
[:group
Expand All @@ -71,7 +71,7 @@
:break :break])
(v/-block "More information:" (v/-link "https://cljdoc.org/d/metosin/malli/CURRENT" printer) printer)]}))

(defmethod v/-format ::m/child-error [_ _ {:keys [type children properties] :as data} printer]
(defmethod v/-format ::m/child-error [_ {:keys [type children properties] :as data} printer]
(let [form (m/-raw-form type properties children)
constraints (reduce (fn [acc k] (if-let [v (get data k)] (assoc acc k v) acc)) nil [:min :max])
size (count children)]
Expand All @@ -83,7 +83,7 @@
", expected " (v/-visit constraints printer)] printer) :break :break
(v/-block "More information:" (v/-link "https://cljdoc.org/d/metosin/malli/CURRENT" printer) printer)]}))

(defmethod v/-format ::m/invalid-entry [_ _ {:keys [entry naked-keys]} printer]
(defmethod v/-format ::m/invalid-entry [_ {:keys [entry]} printer]
{:body
[:group
(v/-block "Invalid Entry" (v/-visit (vec entry) printer) printer) :break :break
Expand Down
53 changes: 32 additions & 21 deletions src/malli/dev/virhe.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
(let [colors (:colors printer -dark-colors)
color (get colors color (:error colors))]
#?(:cljs [:span body]
:clj (if color
[:span [:pass (str "\033[38;5;" color "m")] body [:pass "\u001B[0m"]]
[:span body]))))
:clj (if color
[:span [:pass (str "\033[38;5;" color "m")] body [:pass "\u001B[0m"]]
[:span body]))))

;;
;; EDN
Expand Down Expand Up @@ -131,16 +131,24 @@

#?(:clj
(defn -location [e ss]
(let [start-with (fn [f s] (-> f first str (str/starts-with? s)))
[target _ file line] (loop [[f :as fs] (-> e Throwable->map :trace), [s :as ss] ss]
(cond (start-with f s) (recur (rest fs) ss)
(seq (rest ss)) (recur fs (rest ss))
:else f))]
(try (let [file-name (str/replace file #"(.*?)\.\S[^\.]+" "$1")
target-name (name target)
ns (str (subs target-name 0 (or (str/index-of target-name (str file-name "$")) 0)) file-name)]
(str ns ":" line))
(catch Exception _)))))
(try
(let [start-with (fn [f s] (-> f first str (str/starts-with? s)))
[target _ file line] (loop [[f :as fs] (-> e Throwable->map :trace), [s :as ss] ss]
(cond (start-with f s) (recur (rest fs) ss)
(seq (rest ss)) (recur fs (rest ss))
:else f))]
(let [file-name (str/replace file #"(.*?)\.\S[^\.]+" "$1")
target-name (name target)
ns (str (subs target-name 0 (or (str/index-of target-name (str file-name "$")) 0)) file-name)]
(str ns ":" line)))
(catch Exception _))))

#?(:clj
(defn hierarchy [^Class k]
(loop [sk (.getSuperclass k), ks [k]]
(if-not (= sk Object)
(recur (.getSuperclass sk) (conj ks sk))
ks))))

(defn -title [message source {:keys [width] :as printer}]
(let [between (- width (count message) 8 (count source))]
Expand Down Expand Up @@ -172,20 +180,23 @@
;; formatting
;;

(defmulti -format (fn [type _ _ _] type) :default ::default)
(defmulti -format (fn [e _ _] (-> e (ex-data) :type)) :default ::default)

(defmethod -format ::default [_ message data printer]
{:body
[:group
(-block "Message:" (-color :string message printer) printer) :break :break
(-block "Data:" (-visit data printer) printer)]})
(defmethod -format ::default [e data printer]
(if-let [format #(:clj (some (methods -format) (hierarchy (class e))), :cljs nil)]
(format e data printer)
{:body
[:group
(-block "Type:" (-visit (type e) printer) printer) :break :break
(-block "Message:" (-color :string (ex-message e) printer) printer)
(when-let [data (ex-data e)]
[:group :break :break (-block "Ex-data:" (-visit data printer) printer)])]}))

;;
;; documents
;;

(defn -exception-doc [e printer]
(let [{:keys [type data]} (ex-data e)
{:keys [title body] :or {title (:title printer)}} (-format type (ex-message e) data printer)
(let [{:keys [title body] :or {title (:title printer)}} (-format e (-> e (ex-data) :data) printer)
location #?(:clj (-location e (:throwing-fn-top-level-ns-names printer)), :cljs nil)]
(-section title location body printer)))

0 comments on commit b554920

Please sign in to comment.