Meaningful error message for Clojure.Spec validation in :pre

后端 未结 4 1839
耶瑟儿~
耶瑟儿~ 2021-02-05 06:42

I used the last days to dig deeper into clojure.spec in Clojure and ClojureScript.

Until now I find it most useful, to use specs as guards in :pre

4条回答
  •  终归单人心
    2021-02-05 07:30

    This is useful when you don't want to use s/assert, or can not enable s/check-assserts. Improving on MicSokoli's answer:

    :pre simply cares that the values returned are all truthy, so we can convert the return value "Success!\n" to true (for strictness) and throw an error with the explanation and the input data in case the output is not successful.

    (defn validate [spec input]
        (let [explanation (s/explain-str spec input)]
            (if (= explanation "Success!\n") 
                true
                (throw (ex-info explanation {:input input}))))
    

    A variation of this could be this one, but it would run the spec twice:

    (defn validate [spec input]
        (if (s/valid? spec input) 
            true
            (throw (ex-info (s/explain spec input) {:input input}))))
    

    Usage:

    (defn person-name [person]
      {:pre [(validate ::person person)]}
      (str (::first-name person) " " (::last-name person)))
    

提交回复
热议问题