aboutsummaryrefslogtreecommitdiff
path: root/src/clojure/contrib/except/except.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/clojure/contrib/except/except.clj')
-rw-r--r--src/clojure/contrib/except/except.clj75
1 files changed, 46 insertions, 29 deletions
diff --git a/src/clojure/contrib/except/except.clj b/src/clojure/contrib/except/except.clj
index d6dd62d9..e65044dc 100644
--- a/src/clojure/contrib/except/except.clj
+++ b/src/clojure/contrib/except/except.clj
@@ -8,55 +8,72 @@
;;
;; except.clj
;;
+;; Provides functions that make it easy to specify the class and message
+;; when throwing an Exception or Error. The optional message is formatted
+;; using clojure/format.
+;;
;; scgilardi (gmail)
;; Created 07 July 2008
(ns clojure.contrib.except
(:import (clojure.lang Reflector)))
-(declare throw-formatted)
+(declare throwable)
(defn throwf
- "Throws a formatted Exception or Error with an optional message formatted
- like clojure/printf. All arguments are optional:
+ "Throws an Exception or Error with an optional message formatted using
+ clojure/format. All arguments are optional:
class? format? format-args*
- - class defaults to Exception
+ - class defaults to Exception, if present it must name a kind of
+ Throwable
- format is a format string for clojure/format
- - format-args are objects that correspond format specifiers in format."
+ - format-args are objects that correspond to format specifiers in
+ format."
[& args]
- (apply throw-formatted "clojure.contrib.except.throwf" args))
+ (throw (throwable args)))
(defn throw-if
- "Throws a formatted Exception or Error if test is true. args are those
- documented for throwf."
+ "Throws an Exception or Error if test is true. args are those documented
+ for throwf."
[test & args]
(when test
- (apply throw-formatted "clojure.contrib.except.throw_if" args)))
+ (throw (throwable args))))
;; throw-if-not is synonymous with assert, but clojure/assert exists
(defn throw-if-not
- "Throws a formatted Exception or Error if test is false. args are those
- documented for throwf."
+ "Throws an Exception or Error if test is false. args are those documented
+ for throwf."
[test & args]
(when-not test
- (apply throw-formatted "clojure.contrib.except.throw_if_not" args)))
-
-(defn- throw-formatted
- "Internal helper for formatted exceptions. It builds the formatted message,
- creates the exception object, and edits the exception's stack trace to
- exclude frames that are internal to our implementation. The stack trace
- will start with the line in the caller that contains the throwf,
- throw-if, or throw-if-not call."
- [fn-prefix & args]
- (let [[class & [fmt & fmt-args]]
- (if (class? (first args)) args (cons Exception args))
- args (into-array (if fmt [(apply format fmt fmt-args)] []))
- exception (Reflector/invokeConstructor class args)
- raw-trace (.getStackTrace exception)
- not-our-fn? #(not (.startsWith (.getClassName %) fn-prefix))
- trace (into-array (rrest (drop-while not-our-fn? raw-trace)))]
- (.setStackTrace exception trace)
- (throw exception)))
+ (throw (throwable args))))
+
+(defn throw-arg
+ "Throws an IllegalArgumentException. All arguments are optional:
+
+ format? format-args*
+
+ - format is a format string for clojure/format
+ - format-args are objects that correspond to format specifiers in
+ format."
+ [& args]
+ (throw (throwable (cons IllegalArgumentException args))))
+
+(defn- throwable
+ "Constructs a Throwable with an optional formatted message. Its stack
+ trace will begin with our caller's caller. Args are as described for
+ throwf except throwable accepts them as list rather than inline."
+ [args]
+ (let [[class & [fmt & fmt-args]] (if (class? (first args))
+ args
+ (cons Exception args))
+ ctor-args (into-array (if fmt [(apply format fmt fmt-args)] []))
+ throwable (Reflector/invokeConstructor class ctor-args)
+ our-prefix "clojure.contrib.except.throwable"
+ not-us? #(not (.startsWith (.getClassName %) our-prefix))
+ raw-trace (.getStackTrace throwable)
+ edited-trace (into-array (drop 3 (drop-while not-us? raw-trace)))]
+ (.setStackTrace throwable edited-trace)
+ throwable))