From 5bfe0b15860089b58a6a610996cecf33edf8610d Mon Sep 17 00:00:00 2001 From: Alan Dipert Date: Fri, 21 Oct 2011 11:05:47 -0400 Subject: [PATCH] data conveying exception --- src/clj/clojure/core.clj | 24 ++++++++++++++++++ src/clj/clojure/repl.clj | 4 ++- src/jvm/clojure/lang/ExceptionInfo.java | 40 +++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletions(-) create mode 100644 src/jvm/clojure/lang/ExceptionInfo.java diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index b1801e9..b1fe5cd 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -4220,6 +4220,30 @@ (with-out-str (apply println xs))) +(import clojure.lang.ExceptionInfo) +(defn ex-info + "Alpha - subject to change. + Create an instance of ExceptionInfo, a RuntimeException subclass + that carries a map of additional data." + {:added "1.4"} + ([msg map] + (if (map? map) + (ExceptionInfo. msg map) + (throw (IllegalArgumentException. (str "Additional data must be a map: " map))))) + ([msg map cause] + (if (map? map) + (ExceptionInfo. msg map cause) + (throw (IllegalArgumentException. (str "Additional data must be a map: " map)))))) + +(defn ex-data + "Alpha - subject to change. + Returns exception data (a map) if ex is an ExceptionInfo. + Otherwise returns nil." + {:added "1.4"} + [ex] + (when (instance? ExceptionInfo ex) + (.getData ^ExceptionInfo ex))) + (defmacro assert "Evaluates expr and throws an exception if it does not evaluate to logical true." diff --git a/src/clj/clojure/repl.clj b/src/clj/clojure/repl.clj index 3218180..af55a2f 100644 --- a/src/clj/clojure/repl.clj +++ b/src/clj/clojure/repl.clj @@ -251,7 +251,9 @@ str-or-pattern." (pst (root-cause e) e-or-depth)))) ([^Throwable e depth] (binding [*out* *err*] - (println (str (-> e class .getSimpleName) " " (.getMessage e))) + (println (str (-> e class .getSimpleName) " " + (.getMessage e) + (when-let [info (ex-data e)] (str " " info)))) (let [st (.getStackTrace e) cause (.getCause e)] (doseq [el (take depth diff --git a/src/jvm/clojure/lang/ExceptionInfo.java b/src/jvm/clojure/lang/ExceptionInfo.java new file mode 100644 index 0000000..1f6acc2 --- /dev/null +++ b/src/jvm/clojure/lang/ExceptionInfo.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) Rich Hickey. 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. + */ + +package clojure.lang; + +import java.util.Map; + +/** + * Exception that carries data (a map) as additional payload. Clojure programs that need + * richer semantics for exceptions should use this in lieu of defining project-specific + * exception classes. + */ +public class ExceptionInfo extends RuntimeException{ + public final IPersistentMap data; + + public ExceptionInfo(String s, IPersistentMap data) { + super(s); + this.data = data; + } + + public ExceptionInfo(String s, IPersistentMap data, Throwable throwable) { + super(s, throwable); + this.data = data; + } + + public IPersistentMap getData() { + return data; + } + + public String toString() { + return "clojure.lang.ExceptionInfo: " + getMessage() + " " + data.toString(); + } +} -- 1.7.6