(humanize ex)
πLibrary for translating errors into human readable form.
Add siili/humanize
to your project:
Not sure if humanize is for you? We recommend testing it with
lein try
!
Base usage is very simple:
ex->err
function from humanize's namespace to convert exceptions into translated error data:in
input to function is faulty:out
function's output is faulty:unknown
faulty data occurred in unspecified location:in
is a vector where each entry describes one argument to function in the same order as they are defined in function signature:out
is a single value:unknown
is unspecified;; require needed namespaces
(require '[schema.core :as s]
'[humanize.schema :as h])
;; humanize is meant for interop with s/defn functions
(s/defn broken :- s/Str
[x :- s/Int]
x)
;; boilerplate for calling the broken function in invalid way
(defn check [f]
(try
(f)
(catch clojure.lang.ExceptionInfo e
(if (= (-> e ex-data :type)
:schema.core/error)
(h/ex->err e)))))
(check #(broken "two"))
=> {:in ([x "'two' is not an integer."])}
Humanize can only handle the built-in types and structures. For user defined types an additional translator function can be provided to utilize humanize's internal resolver logic.
For example, assuming the following regular expression checking variant schema has been defined by user:
(ns my.ns
(:require [schema.core :as s]
[schema.spec.variant :as variant]
[schema.spec.core :as spec]))
(defrecord RegexString [regex]
s/Schema
(spec [this]
(variant/variant-spec
spec/+no-precondition+
[{:schema s/Str}]
nil
;; take special note of this line, the list at the end is important
(spec/precondition this (partial re-matches regex) #(list 'not-matching regex %))))
(explain [this]
(list 'regex-constrained (s/explain s/Str) regex)))
which is then used to define a custom validator:
(def AtoZ (RegexString. #"[AZ]+"))
(s/defn yelling-alphas :- s/Any
[aagh :- AtoZ]
aagh)
running this through humanize in same manner as above would produce unresolved translation:
(check #(yelling-alphas "123"))
=> {:in ([aagh [not [not-matching #"[AZ]+" "123"]]])}
which isn't that useful. To resolve this, simply provide a additional translations function to ex->err
:
(defn check [f additional-translations]
(try
(f)
(catch clojure.lang.ExceptionInfo e
(if (= (-> e ex-data :type)
:schema.core/error)
(h/ex->err e additional-translations)))))
and call it with your own logic (we recommend clojure/core.match) to get the desired result:
(defn my-translate [x]
(clojure.core.match/match
x
;; this matches with the spec/precondition list in variant spec
['not ['not-matching regex-pattern value]]
(str value " does not match regex pattern " regex-pattern)
:else
x))
(check #(yelling-alphas "123") my-translate)
=> {:in ([aagh "123 does not match regex pattern [AZ]+"])}
AndrΓ© Rauh for the original Plumatic Schema exception unroller.
spec.alpha
see bhb/expoundCopyright Β© 2018 Siili Solutions
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
Γ close