MichaelDrogalis / dire

Erlang-style supervisor error handling for Clojure
483 stars 19 forks source link

Allow multi pre/post conditions #12

Closed rodnaph closed 11 years ago

rodnaph commented 11 years ago

There might already be a better way to do this but... it would be nice to be able to specify multiple :preconditions for a handler. My use case being preconditions for handlers that process HTML form data....

(with-handler! #'create-user-entity
  {:preconditions [:name-not-blank :passwords-match]}
  (fn [e & args] ... ))

This way the preconditions can be kept isolated and reusable.

(with-handler! #'create-project-entity
  {:preconditions [:name-not-blank :project-type-valid]
  (fn [e & args] ... ))
rodnaph commented 11 years ago

Just realised you can't do this because you have to explicitly attach the :precondition to a function.

Well, if there's a way to do this kind of thing anyway that would be good. Thanks.

rodnaph commented 11 years ago

To carry on my monologue, I rolled my own...

(defn with-validations
  "Attach validations to the specified functions"
  [v & body]
  (let [all-args (apply hash-map body)
        val-args (dissoc all-args :on-error)]
    (doseq [validator (keys val-args)
            failure-message (vals val-args)]
      (let [identifier (keyword (gensym))]
        (with-precondition! v
          identifier
          validator)
        (with-handler! v
          {:precondition identifier}
          (partial (or (:on-error all-args)
                       (fn [e & args]))
                   failure-message))))))

Which can then be used like...

(with-validations #'create-user-entity
  has-valid-username "Username is not valid"
  has-matching-passwords "The passwords do not match"
  :on-error (fn [message e & args] ...))

Can be improved probably, just a first attempt.

Very nice library though - thanks again!