Fork me on GitHub
#malli
<
2023-05-24
>
Carlo05:05:32

A couple of questions in 🧵 on this simple example:

(def ex-spec-1
  [:map [:foo :keyword]])
(def ex-spec-2
  [:* ex-spec-1])
(m/explain ex-spec-2 [{:foo 3} {:foo :a}])
which returns:
{:schema [:* [:map [:foo :keyword]]],
 :value [{:foo 3} {:foo :a}],
 :errors
 ({:path [0 :foo], :in [0 :foo], :schema :keyword, :value 3}
  {:path [],
   :in [0],
   :schema [:* [:map [:foo :keyword]]],
   :value {:foo 3},
   :type :malli.core/input-remaining})}

Carlo05:05:47

1. you can see that in the schema key in the return value the definition of the schema is expanded out. This is fine in this case, but when you have a lot of nested schema definitions, that becomes a couple pages of unreadable mess. Is there a way I can stop displaying at the first level, in this case [:* ex-spec-1]? 2. is there ever a difference between defining specs how I did it above wrapping the vector specification with malli.core/schema, like (m/schema [:map [:foo :keyword]])? What's the benefit of having both versions? 3. what's the :malli.core/input-remaining error about? Just signaling that there might be other errors?

opqdonut06:05:25

3: input-remaining means that the :* sequence expression didn't manage to consume the whole sequence, i.e. there was extra stuff left over

opqdonut06:05:06

2: if you use malli functions, they'll call m/schema for you, which will result in the schema getting recompiled. That can be a performance problem if the schema is big or used really often. Other than that, it doesn't matter.

opqdonut06:05:56

1: that's a good question. I sometimes end up dissocing :schema from my errors because it's not helping. Using a custom registry might help, but I haven't tried it.

opqdonut06:05:32

did that help?

Carlo06:05:03

Yes, thank you very much @US1LTFF6D!

Carlo06:05:32

I'll share here if I end up with a solution for 1, but in the meantime I'll probably dissoc schema too!

Noah Bogart14:05:29

there's also me/humanize

Carlo14:05:24

Yes, thank @UEENNMX0T, I'm using this from (dev/start! {:report (pretty/reporter)}) so the errors appear automatically in my repl when I run instrumented code. I usually find humanized messages a bit of a hit-or-miss. Many times it's just "Invalid type" 😂

Noah Bogart14:05:46

yeah i wish the humanized errors were better about telling you the difference

☝️ 2
Noah Bogart14:05:05

but they're better than vomiting 10 mb of edn into my console lol

escherize14:05:45

A trick I use for humanization is to print out the received value. You do that by calling humanize with a :wrap function like so:

(me/humanize 
 (m/explain input args) 
 {:wrap 
   (fn [{:keys [value message]}] 
     (str message ", received : " (pr-str value)))})

escherize14:05:24

it doesn’t always help, but it can help figure out which part of your value was incorrect

Carlo14:05:55

what's tru?

escherize14:05:05

typo 😉

😂 2
Noah Bogart14:05:33

oh that's nice

gratitude-thank-you 2
escherize14:05:35

it’s for translation at metabase