annotate src/clojure/contrib/except.clj @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
rev   line source
rlm@10 1 ;; Copyright (c) Stephen C. Gilardi. All rights reserved. The use and
rlm@10 2 ;; distribution terms for this software are covered by the Eclipse Public
rlm@10 3 ;; License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can
rlm@10 4 ;; be found in the file epl-v10.html at the root of this distribution. By
rlm@10 5 ;; using this software in any fashion, you are agreeing to be bound by the
rlm@10 6 ;; terms of this license. You must not remove this notice, or any other,
rlm@10 7 ;; from this software.
rlm@10 8 ;;
rlm@10 9 ;; except.clj
rlm@10 10 ;;
rlm@10 11 ;; Provides functions that make it easy to specify the class, cause, and
rlm@10 12 ;; message when throwing an Exception or Error. The optional message is
rlm@10 13 ;; formatted using clojure.core/format.
rlm@10 14 ;;
rlm@10 15 ;; scgilardi (gmail)
rlm@10 16 ;; Created 07 July 2008
rlm@10 17
rlm@10 18 (ns
rlm@10 19 ^{:author "Stephen C. Gilardi",
rlm@10 20 :doc "Provides functions that make it easy to specify the class, cause, and
rlm@10 21 message when throwing an Exception or Error. The optional message is
rlm@10 22 formatted using clojure.core/format."}
rlm@10 23 clojure.contrib.except
rlm@10 24 (:import (clojure.lang Reflector)))
rlm@10 25
rlm@10 26 (declare throwable)
rlm@10 27
rlm@10 28 (defn throwf
rlm@10 29 "Throws an Exception or Error with an optional message formatted using
rlm@10 30 clojure.core/format. All arguments are optional:
rlm@10 31
rlm@10 32 class? cause? format? format-args*
rlm@10 33
rlm@10 34 - class defaults to Exception, if present it must name a kind of
rlm@10 35 Throwable
rlm@10 36 - cause defaults to nil, if present it must be a Throwable
rlm@10 37 - format is a format string for clojure.core/format
rlm@10 38 - format-args are objects that correspond to format specifiers in
rlm@10 39 format."
rlm@10 40 [& args]
rlm@10 41 (throw (throwable args)))
rlm@10 42
rlm@10 43 (defn throw-if
rlm@10 44 "Throws an Exception or Error if test is true. args are those documented
rlm@10 45 for throwf."
rlm@10 46 [test & args]
rlm@10 47 (when test
rlm@10 48 (throw (throwable args))))
rlm@10 49
rlm@10 50 (defn throw-if-not
rlm@10 51 "Throws an Exception or Error if test is false. args are those documented
rlm@10 52 for throwf."
rlm@10 53 [test & args]
rlm@10 54 (when-not test
rlm@10 55 (throw (throwable args))))
rlm@10 56
rlm@10 57 (defn throw-arg
rlm@10 58 "Throws an IllegalArgumentException. All arguments are optional:
rlm@10 59
rlm@10 60 cause? format? format-args*
rlm@10 61
rlm@10 62 - cause defaults to nil, if present it must be a Throwable
rlm@10 63 - format is a format string for clojure.core/format
rlm@10 64 - format-args are objects that correspond to format specifiers in
rlm@10 65 format."
rlm@10 66 [& args]
rlm@10 67 (throw (throwable (cons IllegalArgumentException args))))
rlm@10 68
rlm@10 69 (defn- throwable?
rlm@10 70 "Returns true if x is a Throwable"
rlm@10 71 [x]
rlm@10 72 (instance? Throwable x))
rlm@10 73
rlm@10 74 (defn- throwable
rlm@10 75 "Constructs a Throwable with optional cause and formatted message. Its
rlm@10 76 stack trace will begin with our caller's caller. Args are as described
rlm@10 77 for throwf except throwable accepts them as list rather than inline."
rlm@10 78 [args]
rlm@10 79 (let [[arg] args
rlm@10 80 [class & args] (if (class? arg) args (cons Exception args))
rlm@10 81 [arg] args
rlm@10 82 [cause & args] (if (throwable? arg) args (cons nil args))
rlm@10 83 message (when args (apply format args))
rlm@10 84 ctor-args (into-array Object
rlm@10 85 (cond (and message cause) [message cause]
rlm@10 86 message [message]
rlm@10 87 cause [cause]))
rlm@10 88 throwable (Reflector/invokeConstructor class ctor-args)
rlm@10 89 our-prefix "clojure.contrib.except$throwable"
rlm@10 90 not-us? #(not (.startsWith (.getClassName %) our-prefix))
rlm@10 91 raw-trace (.getStackTrace throwable)
rlm@10 92 edited-trace (into-array StackTraceElement
rlm@10 93 (drop 3 (drop-while not-us? raw-trace)))]
rlm@10 94 (.setStackTrace throwable edited-trace)
rlm@10 95 throwable))