Exceptions are a perfect tool for flow control, if used judiciously. The 
typical criticism revolves around their incompetent usage, and a more 
general criticism can be made against a mechanism that is subverted all too 
easily.

If you responsibly keep to the "good parts", exceptions could be the way to 
go. Validation is one example where I love them because it happens all 
around, but validation failures are all handled uniformly.

However, I would also urge you to explore other approaches, such as having 
a dynamically-bound variable that collects all the validation failures, 
which will potentially give you better diagnostics than the fail-fast 
behavior of validation excptions.

-marko

On Wednesday, March 20, 2013 2:24:12 AM UTC+1, Dave Sann wrote:
>
> I am interested in this view that exceptions are an anti pattern. I have 
> heard it voiced before.
>
> I am not sure that I understand why.
>
> As I see it you have a choices:
>
> 1. Handle in the result  - and test this result repeatedly all the way 
> back to the caller
> 2. Handle "out of band" - Throw an exception, allow the stack to unwind 
> and catch where it matters
>
> [And maybe - but I am not very knowledgeable on this and it won't work 
> today on the JVM anyway
>  3. Use continuation passing style with TCO to shortcut the return to 
> follow an exception path]
>
> So, ignoring 3.
>
> Why is 2 preferable over 1? There are certainly pros and cons.
>
> Dave
>
>
> On Wednesday, 20 March 2013 09:42:11 UTC+11, James Reeves wrote:
>>
>> I'd argue that using exceptions for control flow is something of an 
>> anti-pattern, even in Java.
>>
>> In this case a better mechanism might be to use polymorphism. For 
>> instance:
>>
>> (defprotocol Validatable
>>   (validation-errors [x] "Return the validation errors for x."))
>>
>> (defn valid? [x]
>>   (empty? (validation-errors x)))
>>
>> Then you can define a general function to validate and store that item in 
>> a database:
>>
>> (defn store-valid [db x]
>>   (if (valid? x)
>>     (store db x)
>>     (validation-error-response x)))
>>
>> - James
>>
>>
>> On 19 March 2013 16:43, Julien Dreux <julien...@gmail.com> wrote:
>>
>>> Hi all,
>>>
>>> Coming from a Java background, I am having a hard time understanding how 
>>> validation error propagation should work in clojure web APIs.
>>>
>>> To be clear, this is similar to how my Java web service would be setup:
>>>
>>> /** Method that validates the model, accesses the DB. If something went 
>>> wrong, throw an exception */
>>> public void validateAndCreateUser(User u) throws ValidationException, 
>>> EmailAlreadyInUseException, ... {
>>>   ...
>>>   if(...) {
>>>     throw new ValidationException(fieldName);
>>>   } else if (...) {
>>>     throw new EmailAlreadyInUseException(u.getEmail());
>>>   }
>>> }
>>>
>>> /** Endpoint method, catches & formats the exceptions thrown by the db 
>>> method. **/
>>> @POST("/api/user/create")
>>> public Response createUser (User u)  {
>>>   ..
>>>   try{
>>>     validateAndCreateUser(u);
>>>     return Response.ok();
>>>   } catch (Exception e) {
>>>     return generateExceptionResponse(e); //Method that maps exceptions 
>>> to responses.
>>>   }
>>> }
>>>
>>> For all of Java's clunkiness, this had the benefit of not having to 
>>> write tons of if/else statements for validation handling. Exception were 
>>> just thrown from anywhere, bubbling back up to inital call, and if not 
>>> handled in the endpoint method, a specialized class mapped them into a 
>>> proper response. The exceptions contained all the information needed to 
>>> generate 'rich' error messages back to the client.
>>>
>>> Being a Clojure newbie, I wonder what a good pattern is for a similar 
>>> situation. So far, I have a method that validates models based on a schema, 
>>> that returns
>>>
>>> {:success true}
>>>
>>> or 
>>>
>>> {:success false :errors ["error 1" "error 2" ...]}
>>>
>>> But I don't know how to avoid having to write if/else conditions of the 
>>> sort in each function between my endpoint and db functions.
>>>
>>> (if (validation :success)
>>>   (follow-normal-path)
>>>   (handle-validation-errors validation))
>>>
>>>
>>> Any guidance appreciated.
>>>
>>> Cheers,
>>>
>>> Julien
>>>
>>> -- 
>>> -- 
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>  
>>>  
>>>
>>
>>

-- 
-- 
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/groups/opt_out.


Reply via email to