Go ahead; throw an exception

Clojure, Python, and other modern programming languages lend themselves to the kind of code in which functions are called in all kinds of places, passed as parameters, returned from functions, and so on. In those instances, handling exceptions becomes tricky. It is not like the good old days of C/C++ coding, or at least today’s software seems less like those days.

Recently, while re-writing some Clojure code that depended on data extraction based on nth into functions that processed sequences of maps, I looked at the vulnerability of the new functions. They assumed the right data was being passed to them. I thought, well what if someone passes a sequences of vectors or lists?

The following functions show an example of what I needed and its solution. There is undoubtedly a better way to have done this, but at least this stops me dead in my tracks, so I can go fix a problem more easily.


(defn seq-of-maps?
  "Tests for a sequence of maps, and throws a custom exception if not."

  [s-o-m]
  (if-not (seq? s-o-m)
    (throw (IllegalArgumentException. "s-o-m is not a sequence"))
    (if-not (map? (first s-o-m))
      (throw (IllegalArgumentException. "s-o-m is not a sequence of maps."))
      true)))

(defn ret-map-col
  "Selects a key from a sequence of maps using a map key."

  [in-key in-seq]
  (if (seq-of-maps? in-seq)
    (map (fn [x] (in-key x)) in-seq)
    nil))

Advertisements

3 Comments

Filed under Clojure

3 responses to “Go ahead; throw an exception

  1. The answer is preconditions, helpfully built into defn:

    (defn ret-map-col
      "..."
      [in-key in-seq]
      {:pre [(seq? in-seq)
             (every? map? in-seq)]}
      ;; ...
      )
    

    Preconditions compile to Java assertions which can be turned off in production if you like. On the downside they don’t (yet) let you specify a custom message so their reporting can look gross.

    http://blog.fogus.me/2009/12/21/clojures-pre-and-post/

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s