Fork me on GitHub
#malli
<
2021-10-18
>
andre.richards14:10:23

The malli pretty printer (virhe) is failing when it tries to print a datomic db. It might not be a defect in malli/virhe (see details below), so is there a way to exclude certain fields from pretty printing as a workaround? I'm starting malli.dev with

(malli.dev/start! {:report (pretty/reporter)})
Take for example this function:
(defn fetch-user
  "Fetches a user by its entity `id`. If no entity is found, nil is returned."

  {:malli/schema
   [:=> [:cat :int :any]
    [:maybe :map]]}

  [id db]

  ...)
The db (second) parameter is defined as :any - I'm not even interested in checking that it is a valid db right now, I just want to ensure the id is of valid type. When I call the function with a valid id (:int) and db: (fetch-user 96757023244461 db), it works as expected. However when calling it with a string or anything else in the first position (`id`), it results in this:
(fetch-user "96757023244461" (db/current))

Execution error at malli.dev.virhe.EdnPrinter/visit_set (virhe.cljc:80).
Unable to convert: class datomic.core.btset.BTSet to Object[]
i.e. it is not printing the malli error as it should, but instead it fails with the above. Passing anything else in the second argument, and still the (incorrect type) string in first argument, prints the malli error as expected:
-- Schema Error ---------------------------------------------------

Invalid function arguments:

  ["96757023244461" nil]

Input Schema:

  [:cat :int :any]

Errors:

  {:in [0],
   :message "should be an integer",
   :path [0],
   :schema :int,
   :type nil,
   :value "96757023244461"}
I have attached the stacktrace for when the error can not be pretty printed (i.e. when an actual datomic db is passed). Presumably it is traversing the db object's fields(?) and fails when it gets to the datomic.core.btset.BTSet and tries to convert it to an array. It's not clear to me why datomic's BTSet is failing at that point, and it might not be a defect in malli, but is there a way to exclude certain fields from pretty printing, in order to work around this issue?

ikitommi15:10:32

oh, [malli.dev.virhe.EdnPrinter visit_set "virhe.cljc" 80] <- the datomic.core.btset.BTSet is kinda like set, but not?

andre.richards16:10:46

That's what it looks like, yeah

ikitommi15:10:23

(visit-set [this x]
    (let [xs (sort-by identity (fn [a b] (arrangement.core/rank a b)) x)]
      (fipp.edn/pretty-coll this "#{" xs :line "}" fipp.visit/visit)))

ikitommi15:10:54

@andre.richards if you can make that sort-by wotk with datomic.core.btset.BTSet without extra deps, PR most welcome

andre.richards16:10:13

I will see what I can come up with

andre.richards16:10:04

Will maybe ask on Datomic forum what is up with that BTSet

dominicm17:10:10

Calling seq on your argument might work.

☝️ 2
👏 1
andre.richards11:11:45

This works. I will open an issue and a pull request.