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.

Reply via email to