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.dr...@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 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. > > > -- -- 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.