From bb9402e0ce2593ec3a86c978286b24be24308efd Mon Sep 17 00:00:00 2001
From: Alan Malloy <alan@malloys.org>
Date: Wed, 6 Mar 2013 13:00:28 -0800
Subject: [PATCH] Make Delay save and rethrow exceptions it encounters.

---
 src/jvm/clojure/lang/Delay.java      |   13 ++++++++++++-
 test/clojure/test_clojure/delays.clj |   21 +++++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletions(-)
 create mode 100644 test/clojure/test_clojure/delays.clj

diff --git a/src/jvm/clojure/lang/Delay.java b/src/jvm/clojure/lang/Delay.java
index c8227fe..ef8110b 100644
--- a/src/jvm/clojure/lang/Delay.java
+++ b/src/jvm/clojure/lang/Delay.java
@@ -14,11 +14,13 @@ package clojure.lang;
 
 public class Delay implements IDeref, IPending{
 Object val;
+Throwable exception;
 IFn fn;
 
 public Delay(IFn fn){
 	this.fn = fn;
 	this.val = null;
+        this.exception = null;
 }
 
 static public Object force(Object x) {
@@ -30,9 +32,18 @@ static public Object force(Object x) {
 synchronized public Object deref() {
 	if(fn != null)
 		{
-		val = fn.invoke();
+		try
+			{
+			val = fn.invoke();
+			}
+		catch(Throwable t)
+			{
+			exception = t;
+			}
 		fn = null;
 		}
+	if(exception != null)
+		throw Util.sneakyThrow(exception);
 	return val;
 }
 
diff --git a/test/clojure/test_clojure/delays.clj b/test/clojure/test_clojure/delays.clj
new file mode 100644
index 0000000..0de3341
--- /dev/null
+++ b/test/clojure/test_clojure/delays.clj
@@ -0,0 +1,21 @@
+(ns clojure.test-clojure.delays
+  (:use clojure.test))
+
+(deftest calls-once
+  (let [a (atom 0)
+        d (delay (swap! a inc))]
+    (is (= 0 @a))
+    (is (= 1 @d))
+    (is (= 1 @d))
+    (is (= 1 @a))))
+
+(deftest saves-exceptions
+  (let [f #(do (throw (Exception. "broken"))
+               1)
+        d (delay (f))
+        try-call #(try
+                    @d
+                    (catch Exception e e))
+        first-result (try-call)]
+    (is (instance? Exception first-result))
+    (is (identical? first-result (try-call)))))
-- 
1.7.4.1

