I agree with you that an IllegalArgumentException is preferable to AssertionError. The reason that I used AssertionError was that I wanted to keep the same behaviour as when using s/valid? (it throws an AssertionError). Maybe only s/assert should throw AssertionError and s/valid? should throw something else?
/Joakim On Friday, September 16, 2016 at 7:52:55 AM UTC+2, Mamun wrote: > > > When function is throwing exception because of argument. I would prefer to > throw IllegalArgumentException not AssertionError. > > > (defn check [type data] > (if (sp/valid? type data) > true > (throw (IllegalArgumentException. (sp/explain type data))))) > > > Br, > Mamun > > > On Friday, September 16, 2016 at 7:20:53 AM UTC+2, joakim.t...@nova.com > wrote: >> >> I came up with this solution: >> >> (ns spec-test.core >> (:require [clojure.spec :as s])) >> >> (s/def :user/name string?) >> (s/def :common/user (s/keys :req [:user/name])) >> >> ;; with this little helper function... >> (defn check [type data] >> (if (s/valid? type data) >> true >> (throw (AssertionError. (s/explain type data))))) >> >> ;; I can use it in my :pre condition >> (defn aname [user] >> {:pre [(check :common/user user)]} >> (-> user :user/name)) >> >> ;; when I call name with an illegal arguement... >> (aname {:x "Elon"}) >> >> ;; ...it not fails and returns a better error message: >> CompilerException java.lang.AssertionError: null, >> compiling:(/Users/joakimtengstrand/IdeaProjects/spec-test/src/spec_test/core.clj:19:1) >> val: {:x "Elon"} fails spec: :common/user predicate: (contains? % :user/name) >> >> >> With this solution I don't need to enable assertions, and the code is >> neat and less verbose! >> >> /Joakim >> >> On Thursday, September 15, 2016 at 3:11:32 PM UTC+2, Shantanu Kumar wrote: >>> >>> Hi Joakim, >>> >>> You might be interested in Paul Stadig's library >>> https://github.com/pjstadig/assertions that leverages Java's `-ea` >>> (enable-assertions, which you may want to keep enabled in dev) command-line >>> flag. If you have a bunch of things together to assert, you may want to use >>> the `when-assert` macro for wholesale optimization: >>> https://github.com/pjstadig/assertions/blob/0.2.0/src/pjstadig/assertions.clj#L13 >>> >>> >>> Shantanu >>> >>> On Thursday, 15 September 2016 16:50:17 UTC+5:30, joakim.t...@nova.com >>> wrote: >>>> >>>> Ok, thanks! >>>> >>>> In the Java world, the assertions is also something that need to be >>>> turn on explicitly. >>>> In that sence, they are kind of not mandatory to be executed (or at >>>> least signals that to the reader of the code). >>>> >>>> I would be happier if you guys could add another method, that I can use >>>> in my :pre conditions, that leverage >>>> the same amount of details in the error messages, but that is always >>>> "turned on". >>>> >>>> In the meanwhile, I will use s/assert ;-) >>>> >>>> BR, >>>> Joakim Tengstrand >>>> >>>> >>>> On Wednesday, 14 September 2016 15:59:09 UTC+2, Alex Miller wrote: >>>>> >>>>> 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.t...@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.