aboutsummaryrefslogtreecommitdiff
path: root/src/clojure/contrib/condition.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/clojure/contrib/condition.clj')
-rw-r--r--src/clojure/contrib/condition.clj147
1 files changed, 0 insertions, 147 deletions
diff --git a/src/clojure/contrib/condition.clj b/src/clojure/contrib/condition.clj
deleted file mode 100644
index 98aa589a..00000000
--- a/src/clojure/contrib/condition.clj
+++ /dev/null
@@ -1,147 +0,0 @@
-;; Copyright (c) Stephen C. Gilardi. All rights reserved. The use and
-;; distribution terms for this software are covered by the Eclipse Public
-;; License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can
-;; be found in the file epl-v10.html at the root of this distribution. By
-;; using this software in any fashion, you are agreeing to be bound by the
-;; terms of this license. You must not remove this notice, or any other,
-;; from this software.
-;;
-;; condition.clj
-;;
-;; scgilardi (gmail)
-;; Created 09 June 2009
-
-(ns #^{:author "Stephen C. Gilardi"
- :doc "Flexible raising and handling of conditions:
-
-Functions:
-
- raise: raises a condition
- handler-case: dispatches raised conditions to appropriate handlers
- print-stack-trace: prints abbreviated or full condition stack traces
-
-Data:
-
- A condition is a map containing values for these keys:
-
- - :type, a condition type specifier, typically a keyword
- - :stack-trace, a stack trace to the site of the raise
- - :message, a human-readable message (optional)
- - :cause, a wrapped exception or condition (optional)
- - other keys given as arguments to raise (optional)
-
-Note: requires AOT compilation.
-
-Based on an idea from Chouser:
-http://groups.google.com/group/clojure/browse_frm/thread/da1285c538f22bb5"}
- clojure.contrib.condition
- (:require clojure.contrib.condition.Condition)
- (:import clojure.contrib.condition.Condition
- clojure.lang.IPersistentMap)
- (:use (clojure.contrib
- [def :only (defvar)]
- [seq-utils :only (separate)])))
-
-(defvar *condition*
- "While a handler is running, bound to the condition being handled")
-
-(defvar *selector*
- "While a handler is running, bound to the selector returned by the
- handler-case dispatch-fn for *condition*")
-
-(defvar *condition-object*
- "While a handler is running, bound to the Condition object whose metadata
- is the condition")
-
-(defvar *full-stack-traces* false
- "Bind to true to include clojure.{core,lang,main} frames in stack
- traces")
-
-(defmacro raise
- "Raises a condition. With no arguments, re-raises the current condition.
- With one argument (a map), raises the argument. With two or more
- arguments, raises a map with keys and values from the arguments."
- ([]
- `(throw *condition-object*))
- ([m]
- `(throw (Condition. ~m)))
- ([key val & keyvals]
- `(raise (hash-map ~key ~val ~@keyvals))))
-
-(defmacro handler-case
- "Executes body in a context where raised conditions can be handled.
-
- dispatch-fn accepts a raised condition (a map) and returns a selector
- used to choose a handler. Commonly, dispatch-fn will be :type to dispatch
- on the condition's :type value.
-
- Handlers are forms within body:
-
- (handle key
- ...)
-
- If a condition is raised, executes the body of the first handler whose
- key satisfies (isa? selector key). If no handlers match, re-raises the
- condition.
-
- While a handler is running, *condition* is bound to the condition being
- handled and *selector* is bound to to the value returned by dispatch-fn
- that matched the handler's key."
- [dispatch-fn & body]
- (let [[handlers code]
- (separate #(and (list? %) (= 'handle (first %))) body)]
- `(try
- ~@code
- (catch Condition c#
- (binding [*condition-object* c#
- *condition* (meta c#)
- *selector* (~dispatch-fn (meta c#))]
- (cond
- ~@(mapcat
- (fn [[_ key & body]]
- `[(isa? *selector* ~key) (do ~@body)])
- handlers)
- :else (raise)))))))
-
-(defmulti stack-trace-info
- "Returns header, stack-trace, and cause info from conditions and
- Throwables"
- class)
-
-(defmethod stack-trace-info IPersistentMap
- [condition]
- [(format "condition: %s, %s" (:type condition)
- (dissoc condition :type :stack-trace :cause))
- (:stack-trace condition)
- (:cause condition)])
-
-(defmethod stack-trace-info Condition
- [condition]
- (stack-trace-info (meta condition)))
-
-(defmethod stack-trace-info Throwable
- [throwable]
- [(str throwable)
- (.getStackTrace throwable)
- (.getCause throwable)])
-
-(defn print-stack-trace
- "Prints a stack trace for a condition or Throwable. Skips frames for
- classes in clojure.{core,lang,main} unless the *full-stack-traces* is
- bound to logical true"
- [x]
- (let [[header frames cause] (stack-trace-info x)]
- (printf "%s\n" header)
- (doseq [frame frames]
- (let [classname (.getClassName frame)]
- (if (or *full-stack-traces*
- (not (re-matches
- #"clojure.(?:core|lang|main).*" classname)))
- (printf " at %s/%s(%s:%s)\n"
- classname
- (.getMethodName frame)
- (.getFileName frame)
- (.getLineNumber frame)))))
- (when cause
- (printf "caused by: ")
- (recur cause))))