malli

https://github.com/metosin/malli :malli:
ikitommi 2021-06-24T04:56:49.209200Z

@escherize maybe:

(-> [:map
     [:something/one {:error/message "one"} int?]
     [:something/two {:error/message "2"} int?]
     [:something/three {:error/message "three"} int?]
     [:something/four {:error/message "four"} int?]]
    (m/explain {})
    (me/humanize {:resolve me/resolve-root-error}))
; => #:something{:one ["one"]:two ["2"], :three ["three"], :four ["four"]}

ikitommi 2021-06-24T04:58:42.210300Z

that’s in master, but not released. can be used, but will most likely change it to be a separate step, something like:

(-> Schema
    (m/explain {})
    (me/root-causes)
    (me/humanize))
; => #:something{:one ["one"]:two ["2"], :three ["three"], :four ["four"]}

ikitommi 2021-06-24T05:01:52.212500Z

anyway, it’s generic, so will find the top-most error defined:

(-> [:cat {:error/message "oh no!"}
     [:? [:map-of :string :any]]
     [:* :boolean]]
    (m/explain 123)
    (me/humanize {:resolve me/resolve-root-error}))
; => ["oh no!"]

ikitommi 2021-06-24T05:02:51.213700Z

there is a perf hit of recurring all errors towards root, but it can be later removed with an extra step of preparing a me/humanizer.

escherize 2021-06-24T05:57:47.214200Z

Awesome. I’ll look into this. Thanks @ikitommi