malli

Juan José Vázquez Delgado 2024-11-10T13:31:00.538379Z

Hi! Just starting with Malli and I'm not able to get the error messages I would like. Suppose we have a schema like this

(def foo-schema
  [:or :string :boolean])
after the assertion I will get a message like this:
(try (m/assert foo-schema 10)
     (catch ExceptionInfo e
       (let [explanation (-> e ex-data :data :explain)
             error-messages (me/humanize explanation)]
         (println error-messages)))) ;; [should be a string should be a boolean]
But I would like to have a custom message for the whole thing. Tried this:
(def foo-schema
  [:or {:error/message "not a valid type"} :string :boolean])
but it's not working. I still get the general error [should be a string should be a boolean]. Any ideas?.

Juan José Vázquez Delgado 2024-11-11T08:58:43.149359Z

Thanks for your help!. I have tested both approaches. The first one with the :or schema still won't work. I keep getting the low level messages ["should be a string" "should be a boolean"]. The second one, with the function schema, does work but here you don't need the -resolve-root-error function. It works without it. I will go for this solution. Thanks!.

👍 1
2024-11-10T22:43:38.751119Z

Some help in the https://github.com/metosin/malli?tab=readme-ov-file#custom-error-messages By default, only direct erroneous schema properties are used:

(-> [:map
     [:foo {:error/message "entry-failure"} :int]] ;; here, :int fails, no error props
    (m/explain {:foo "1"})
    (me/humanize))
; => {:foo ["should be an integer"]}

2024-11-10T22:44:28.104349Z

Looking up humanized errors from parent schemas with custom :resolve (BETA, subject to change):

(-> [:map
     [:foo {:error/message "entry-failure"} :int]]
    (m/explain {:foo "1"})
    (me/humanize {:resolve me/-resolve-root-error}))
; => {:foo ["entry-failure"]}

2024-11-10T22:46:30.632429Z

So this might get you close:

(let [schema [:or {:error/message "not a valid type"} :string :boolean]]
    (-> 10
        (->> (m/explain schema))
        (me/humanize {:resolve me/-resolve-root-error})))
;; => ["not a valid type" "not a valid type"]

2024-11-10T22:47:49.240359Z

Another option is to use a function schema:

(let [schema [:fn {:error/message "not a valid type"}
                (fn [x] (or (string? x) (boolean? x)))]]
    (-> 10
        (->> (m/explain schema))
        (me/humanize {:resolve me/-resolve-root-error})))
  ;; => ["not a valid type"]