Use exception/fail! in all creation-time exceptions

... to be companioned with a slick error printer
This commit is contained in:
Tommi Reiman 2019-02-09 16:51:34 +02:00
parent ad92c437e6
commit 950fef88d2
9 changed files with 63 additions and 68 deletions

View file

@ -1,6 +1,7 @@
(ns reitit.core (ns reitit.core
(:require [clojure.string :as str] (:require [clojure.string :as str]
[reitit.impl :as impl] [reitit.impl :as impl]
[reitit.exception :as exception]
[reitit.trie :as trie])) [reitit.trie :as trie]))
;; ;;
@ -50,10 +51,7 @@
conflicts))) conflicts)))
(defn throw-on-conflicts! [f conflicts] (defn throw-on-conflicts! [f conflicts]
(throw (exception/fail! (f conflicts) {:conflicts conflicts}))
(ex-info
(f conflicts)
{:conflicts conflicts})))
;; ;;
;; Router ;; Router
@ -149,11 +147,10 @@
(lookup-router compiled-routes {})) (lookup-router compiled-routes {}))
([compiled-routes opts] ([compiled-routes opts]
(when-let [wilds (seq (filter impl/wild-route? compiled-routes))] (when-let [wilds (seq (filter impl/wild-route? compiled-routes))]
(throw (exception/fail!
(ex-info (str "can't create :lookup-router with wildcard routes: " wilds)
(str "can't create :lookup-router with wildcard routes: " wilds) {:wilds wilds
{:wilds wilds :routes compiled-routes}))
:routes compiled-routes})))
(let [names (impl/find-names compiled-routes opts) (let [names (impl/find-names compiled-routes opts)
[pl nl] (reduce [pl nl] (reduce
(fn [[pl nl] [p {:keys [name] :as data} result]] (fn [[pl nl] [p {:keys [name] :as data} result]]
@ -239,10 +236,9 @@
(single-static-path-router compiled-routes {})) (single-static-path-router compiled-routes {}))
([compiled-routes opts] ([compiled-routes opts]
(when (or (not= (count compiled-routes) 1) (some impl/wild-route? compiled-routes)) (when (or (not= (count compiled-routes) 1) (some impl/wild-route? compiled-routes))
(throw (exception/fail!
(ex-info (str ":single-static-path-router requires exactly 1 static route: " compiled-routes)
(str ":single-static-path-router requires exactly 1 static route: " compiled-routes) {:routes compiled-routes}))
{:routes compiled-routes})))
(let [[n :as names] (impl/find-names compiled-routes opts) (let [[n :as names] (impl/find-names compiled-routes opts)
[[p data result]] compiled-routes [[p data result]] compiled-routes
p #?(:clj (.intern ^String p) :cljs p) p #?(:clj (.intern ^String p) :cljs p)

View file

@ -1,5 +1,6 @@
(ns reitit.dependency (ns reitit.dependency
"Dependency resolution for middleware/interceptors.") "Dependency resolution for middleware/interceptors."
(:require [reitit.exception :as exception]))
(defn- providers (defn- providers
"Map from provision key to provider. `get-provides` should return the provision keys of a dependent." "Map from provision key to provider. `get-provides` should return the provision keys of a dependent."
@ -8,8 +9,9 @@
(into acc (into acc
(map (fn [provide] (map (fn [provide]
(when (contains? acc provide) (when (contains? acc provide)
(throw (ex-info (str "multiple providers for: " provide) (exception/fail!
{::multiple-providers provide}))) (str "multiple providers for: " provide)
{::multiple-providers provide}))
[provide dependent])) [provide dependent]))
(get-provides dependent))) (get-provides dependent)))
{} nodes)) {} nodes))
@ -19,8 +21,9 @@
[providers k] [providers k]
(if (contains? providers k) (if (contains? providers k)
(get providers k) (get providers k)
(throw (ex-info (str "provider missing for dependency: " k) (exception/fail!
{::missing-provider k})))) (str "provider missing for dependency: " k)
{::missing-provider k})))
(defn post-order (defn post-order
"Put `nodes` in post-order. Can also be described as a reverse topological sort. "Put `nodes` in post-order. Can also be described as a reverse topological sort.
@ -37,8 +40,7 @@
(assoc colors node :grey))] (assoc colors node :grey))]
[(conj nodes* node) [(conj nodes* node)
(assoc colors node :black)]) (assoc colors node :black)])
:grey (throw (ex-info "circular dependency" :grey (exception/fail! "circular dependency" {:cycle (drop-while #(not= % node) (conj path node))})
{:cycle (drop-while #(not= % node) (conj path node))}))
:black [() colors])) :black [() colors]))
(toposort-seq [nodes path colors] (toposort-seq [nodes path colors]

View file

@ -2,6 +2,6 @@
(defn fail! (defn fail!
([message] ([message]
(throw (ex-info message {:type ::exeption}))) (throw (ex-info message {::type :exeption})))
([message data] ([message data]
(throw (ex-info message (assoc data :type ::exeption))))) (throw (ex-info message (merge {::type ::exeption} data)))))

View file

@ -3,7 +3,8 @@
(:require [clojure.string :as str] (:require [clojure.string :as str]
[clojure.set :as set] [clojure.set :as set]
[meta-merge.core :as mm] [meta-merge.core :as mm]
[reitit.trie :as trie]) [reitit.trie :as trie]
[reitit.exception :as exception])
#?(:clj #?(:clj
(:import (java.util.regex Pattern) (:import (java.util.regex Pattern)
(java.util HashMap Map) (java.util HashMap Map)
@ -126,10 +127,9 @@
(when-not (every? #(contains? path-params %) required) (when-not (every? #(contains? path-params %) required)
(let [defined (-> path-params keys set) (let [defined (-> path-params keys set)
missing (set/difference required defined)] missing (set/difference required defined)]
(throw (exception/fail!
(ex-info (str "missing path-params for route " template " -> " missing)
(str "missing path-params for route " template " -> " missing) {:path-params path-params, :required required}))))
{:path-params path-params, :required required})))))
(defn fast-assoc (defn fast-assoc
#?@(:clj [[^clojure.lang.Associative a k v] (.assoc a k v)] #?@(:clj [[^clojure.lang.Associative a k v] (.assoc a k v)]

View file

@ -2,7 +2,8 @@
(:require [meta-merge.core :refer [meta-merge]] (:require [meta-merge.core :refer [meta-merge]]
[clojure.pprint :as pprint] [clojure.pprint :as pprint]
[reitit.core :as r] [reitit.core :as r]
[reitit.impl :as impl])) [reitit.impl :as impl]
[reitit.exception :as exception]))
(defprotocol IntoInterceptor (defprotocol IntoInterceptor
(into-interceptor [this data opts])) (into-interceptor [this data opts]))
@ -33,10 +34,9 @@
#?(:clj clojure.lang.Keyword #?(:clj clojure.lang.Keyword
:cljs cljs.core.Keyword) :cljs cljs.core.Keyword)
(into-interceptor [this data {:keys [::registry] :as opts}] (into-interceptor [this data {:keys [::registry] :as opts}]
(if-let [interceptor (if registry (registry this))] (or (if-let [interceptor (if registry (registry this))]
(into-interceptor interceptor data opts) (into-interceptor interceptor data opts))
(throw (exception/fail!
(ex-info
(str (str
"Interceptor " this " not found in registry.\n\n" "Interceptor " this " not found in registry.\n\n"
(if (seq registry) (if (seq registry)
@ -46,16 +46,15 @@
(pprint/print-table [:id :description] (for [[k v] registry] {:id k :description v})))) (pprint/print-table [:id :description] (for [[k v] registry] {:id k :description v}))))
"see [reitit.interceptor/router] on how to add interceptor to the registry.\n") "\n") "see [reitit.interceptor/router] on how to add interceptor to the registry.\n") "\n")
{:id this {:id this
:registry registry})))) :registry registry})))
#?(:clj clojure.lang.APersistentVector #?(:clj clojure.lang.APersistentVector
:cljs cljs.core.PersistentVector) :cljs cljs.core.PersistentVector)
(into-interceptor [[f & args :as form] data opts] (into-interceptor [[f & args :as form] data opts]
(when (and (seq args) (not (fn? f))) (when (and (seq args) (not (fn? f)))
(throw (exception/fail!
(ex-info (str "Invalid Interceptor form: " form "")
(str "Invalid Interceptor form: " form "") {:form form}))
{:form form})))
(into-interceptor (apply f args) data opts)) (into-interceptor (apply f args) data opts))
#?(:clj clojure.lang.Fn #?(:clj clojure.lang.Fn
@ -85,10 +84,9 @@
(let [compiled (::compiled opts 0) (let [compiled (::compiled opts 0)
opts (assoc opts ::compiled (inc ^long compiled))] opts (assoc opts ::compiled (inc ^long compiled))]
(when (>= ^long compiled ^long *max-compile-depth*) (when (>= ^long compiled ^long *max-compile-depth*)
(throw (exception/fail!
(ex-info (str "Too deep Interceptor compilation - " compiled)
(str "Too deep Interceptor compilation - " compiled) {:this this, :data data, :opts opts}))
{:this this, :data data, :opts opts})))
(if-let [interceptor (into-interceptor (compile data opts) data opts)] (if-let [interceptor (into-interceptor (compile data opts) data opts)]
(map->Interceptor (map->Interceptor
(merge (merge

View file

@ -2,7 +2,8 @@
(:require [meta-merge.core :refer [meta-merge]] (:require [meta-merge.core :refer [meta-merge]]
[clojure.pprint :as pprint] [clojure.pprint :as pprint]
[reitit.core :as r] [reitit.core :as r]
[reitit.impl :as impl])) [reitit.impl :as impl]
[reitit.exception :as exception]))
(defprotocol IntoMiddleware (defprotocol IntoMiddleware
(into-middleware [this data opts])) (into-middleware [this data opts]))
@ -17,10 +18,9 @@
#?(:clj clojure.lang.Keyword #?(:clj clojure.lang.Keyword
:cljs cljs.core.Keyword) :cljs cljs.core.Keyword)
(into-middleware [this data {:keys [::registry] :as opts}] (into-middleware [this data {:keys [::registry] :as opts}]
(if-let [middleware (if registry (registry this))] (or (if-let [middleware (if registry (registry this))]
(into-middleware middleware data opts) (into-middleware middleware data opts))
(throw (exception/fail!
(ex-info
(str (str
"Middleware " this " not found in registry.\n\n" "Middleware " this " not found in registry.\n\n"
(if (seq registry) (if (seq registry)
@ -30,7 +30,7 @@
(pprint/print-table [:id :description] (for [[k v] registry] {:id k :description v})))) (pprint/print-table [:id :description] (for [[k v] registry] {:id k :description v}))))
"see [reitit.middleware/router] on how to add middleware to the registry.\n") "\n") "see [reitit.middleware/router] on how to add middleware to the registry.\n") "\n")
{:id this {:id this
:registry registry})))) :registry registry})))
#?(:clj clojure.lang.APersistentVector #?(:clj clojure.lang.APersistentVector
:cljs cljs.core.PersistentVector) :cljs cljs.core.PersistentVector)
@ -61,10 +61,9 @@
(let [compiled (::compiled opts 0) (let [compiled (::compiled opts 0)
opts (assoc opts ::compiled (inc ^long compiled))] opts (assoc opts ::compiled (inc ^long compiled))]
(when (>= ^long compiled ^long *max-compile-depth*) (when (>= ^long compiled ^long *max-compile-depth*)
(throw (exception/fail!
(ex-info (str "Too deep Middleware compilation - " compiled)
(str "Too deep Middleware compilation - " compiled) {:this this, :data data, :opts opts}))
{:this this, :data data, :opts opts})))
(if-let [middeware (into-middleware (compile data opts) data opts)] (if-let [middeware (into-middleware (compile data opts) data opts)]
(map->Middleware (map->Middleware
(merge (merge
@ -76,11 +75,11 @@
(defn- ensure-handler! [path data scope] (defn- ensure-handler! [path data scope]
(when-not (:handler data) (when-not (:handler data)
(throw (ex-info (exception/fail!
(str "path \"" path "\" doesn't have a :handler defined" (str "path \"" path "\" doesn't have a :handler defined"
(if scope (str " for " scope))) (if scope (str " for " scope)))
(merge {:path path, :data data} (merge {:path path, :data data}
(if scope {:scope scope})))))) (if scope {:scope scope})))))
(defn- expand-and-transform (defn- expand-and-transform
[middleware data {:keys [::transform] :or {transform identity} :as opts}] [middleware data {:keys [::transform] :or {transform identity} :as opts}]

View file

@ -1,7 +1,8 @@
(ns reitit.spec (ns reitit.spec
(:require [clojure.spec.alpha :as s] (:require [clojure.spec.alpha :as s]
[clojure.spec.gen.alpha :as gen] [clojure.spec.gen.alpha :as gen]
[reitit.core :as reitit])) [reitit.core :as reitit]
[reitit.exception :as exception]))
;; ;;
;; routes ;; routes
@ -119,10 +120,9 @@
problems))) problems)))
(defn throw-on-problems! [problems explain] (defn throw-on-problems! [problems explain]
(throw (exception/fail!
(ex-info (problems-str problems explain)
(problems-str problems explain) {:problems problems}))
{:problems problems})))
(defn validate-route-data [routes spec] (defn validate-route-data [routes spec]
(->> (for [[p d _] routes] (->> (for [[p d _] routes]

View file

@ -1,7 +1,8 @@
(ns reitit.ring.spec (ns reitit.ring.spec
(:require [clojure.spec.alpha :as s] (:require [clojure.spec.alpha :as s]
[reitit.middleware :as middleware] [reitit.middleware :as middleware]
[reitit.spec :as rs])) [reitit.spec :as rs]
[reitit.exception :as exception]))
;; ;;
;; Specs ;; Specs
@ -19,11 +20,10 @@
(defn merge-specs [specs] (defn merge-specs [specs]
(when-let [non-specs (seq (remove #(or (s/spec? %) (s/get-spec %)) specs))] (when-let [non-specs (seq (remove #(or (s/spec? %) (s/get-spec %)) specs))]
(throw (exception/fail!
(ex-info (str "Not all specs satisfy the Spec protocol: " non-specs)
(str "Not all specs satisfy the Spec protocol: " non-specs) {:specs specs
{:specs specs :non-specs non-specs}))
:non-specs non-specs})))
(s/merge-spec-impl (vec specs) (vec specs) nil)) (s/merge-spec-impl (vec specs) (vec specs) nil))
(defn validate-route-data [routes key spec] (defn validate-route-data [routes key spec]

View file

@ -114,7 +114,7 @@
(throw (throw
(ex-info (ex-info
(str "Can't produce Spec apidocs for " spesification) (str "Can't produce Spec apidocs for " spesification)
{:type spesification, :coercion :spec})))) {:spesification spesification, :coercion :spec}))))
(-compile-model [_ model name] (-compile-model [_ model name]
(into-spec model name)) (into-spec model name))
(-open-model [_ spec] spec) (-open-model [_ spec] spec)