I would like to be able to generate user-friendly or specify custom error messages for validation errors in these schemas:
(def Uuid (s/constrained String #(re-matches #"^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" (name %))))
(def FirstName s/Str)
(def LastName s/Str)
(s/defschema Person {(s/required-key :id) Uuid,
(s/required-key :first-name) FirstName,
(s/required-key :last-name) LastName})
Valid schema:
{
:uuid "e143499c-1257-41e4-b951-c9e586994ff9"
:first-name "john"
:last-name "smith"
}
Invalid schema:
{
:uuid ""
:first-name nil
:last-name nil
}
Invalid schema - Errors:
{
"id" : "(not (app.person/fn--4881 \"\"))",
"first-name" : "(not (instance? java.lang.String nil))"
"last-name" : "(not (instance? java.lang.String nil))"
}
I would like to be able to generate something a bit more readable to non-programmers, for example:
{
"id" : "invalid uuid",
"first-name" : "must be a string"
"last-name" : "must be a string"
}
Funnily exactly this was released as a library a few days ago.
See:
https://github.com/siilisolutions/humanize
First you also need to tag your Uuid
schema so you can match it later on:
;; Note the last param I added:
(def Uuid (sc/constrained
String
#(re-matches #"^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
(name %))
'UUID))
(require '[schema.core :as sc]
'[humanize.schema :as hs])
(#'hs/explain (sc/check Person {:id "foo"
:first-name "foo"
:last-name 3})
(fn [x]
(clojure.core.match/match
x
['not ['UUID xx]]
(str xx " is not a valid UUID")
:else x)))
Results in:
=> {:id "foo is not a valid UUID", :last-name "'3' is not a string but it should be."}
Note, it needed a little trick since hs/explain
is private unfortunately.