Another option that has been added since the guide was written is s/assert which seems closer to what you're suggesting.
(defn name [user] {:pre [(s/assert :common/user user)]} (-> user :user/name)) ;; need to enable assertion checking - this can also be enabled globally with system property clojure.spec.check-asserts (s/check-asserts true) (name {:user/name "Elon"}) "Elon" (name {:x "Elon"}) ExceptionInfo Spec assertion failed val: {:x "Elon"} fails predicate: (contains? % :user/name) :clojure.spec/failure :assertion-failed clojure.core/ex-info (core.clj:4725) Rather than use it in a precondition, you can also use s/assert directly in the code. On Wednesday, September 14, 2016 at 7:37:24 AM UTC-5, joakim.tengstr...@nova.com wrote: > > (ns spec-test.core > (:require [clojure.spec :as s])) > > (s/def :user/name string?) > (s/def :common/user (s/keys :req [:user/name])) > > ; first version of name (using :pre) > (defn name [user] > {:pre [(s/valid? :common/user user)]} > (-> user :user/name)) > > ; This statement works ok and returns "Elon": > (name {:user/name "Elon"}) > > ; but this statement... > (name {:x "Elon"}) > > ;...will throw: > CompilerException java.lang.AssertionError: > Assert failed: (s/valid? :common/user user) > > ; ...but then I don't get as much information > ; about the error as if I would have called: > (s/explain :common/user {:x "Elon"}) > > ;...which also contains the predicate: > val: {:x "Elon"} fails spec: :common/user > predicate: (contains? % :user/name) > > ; (second version of name - more verbose) > ; or do I need to wite it like this: > (defn name [user] > (let [parsed (s/conform :common/user user)] > (if (= parsed ::s/invalid) > (throw (ex-info "Invalid input" (s/explain-data :common/user user))) > (-> user :user/name)))) > > ; so that: > (name {:x "Elon"}) > > ; ...will return: > CompilerException clojure.lang.ExceptionInfo: > Invalid input #:clojure.spec{:problems} > ({:path [], :pred (contains? % :user/name), > :val {:x "Elon"}, :via [:common/user], :in []}) > > ; It should be nice if I could be able to write it like this > ; (or similar, to get a better error message): > (defn name [user] > {:pre [(s/explain :common/user user)]} > (-> user :user/name)) > > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.