-
Notifications
You must be signed in to change notification settings - Fork 250
/
exception.cljc
50 lines (41 loc) · 1.71 KB
/
exception.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
(ns reitit.exception
(:require [clojure.string :as str]))
(defn fail!
([type]
(fail! type nil))
([type data]
(throw (ex-info (str type) {:type type, :data data}))))
(defn get-message [e]
#?(:clj (.getMessage ^Exception e) :cljs (ex-message e)))
(defmulti format-exception (fn [type _ _] type))
(defn exception [e]
(let [data (ex-data e)
message (format-exception (:type data) (get-message e) (:data data))]
;; there is a 3-arity version (+cause) of ex-info, but the default repl error message is taken from the cause
(ex-info message (assoc (or data {}) ::cause e))))
;;
;; Formatters
;;
(defmethod format-exception :default [_ message data]
(str message (if data (str "\n\n" (pr-str data)))))
(defmethod format-exception :path-conflicts [_ _ conflicts]
(letfn [(resolve-str [path route-data]
(str (if (:conflicting route-data) " " "-> ")
path " " (not-empty (select-keys route-data [:conflicting]))))]
(apply str "Router contains conflicting route paths:\n\n"
(mapv
(fn [[[path route-data] vals]]
(str (resolve-str path route-data)
"\n"
(str/join "\n" (mapv (fn [[path route-data]]
(resolve-str path route-data)) vals))
"\n\n"))
conflicts))))
(defmethod format-exception :name-conflicts [_ _ conflicts]
(apply str "Router contains conflicting route names:\n\n"
(mapv
(fn [[name vals]]
(str name "\n-> " (str/join "\n-> " (mapv first vals)) "\n"))
conflicts)))
(defmethod format-exception :reitit.impl/merge-data [_ _ data]
(str "Error merging route-data\n\n" (pr-str data)))