Skip to content

Commit e5884cd

Browse files
committed
Implement CompletionStage exceptionally
1 parent eac3dc2 commit e5884cd

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

src/manifold/deferred.clj

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@
6868

6969
then-compose then-compose-async
7070

71-
then-handle then-handle-async)
71+
then-handle then-handle-async
72+
then-exceptionally)
7273

7374
;; The potemkin abstract type for
7475
;; implementations such as CompletionStage
@@ -149,7 +150,10 @@
149150
(handleAsync [this operator]
150151
(then-handle-async this operator))
151152
(handleAsync [this operator executor]
152-
(then-handle-async this operator executor)))
153+
(then-handle-async this operator executor))
154+
155+
(exceptionally [this operator]
156+
(then-exceptionally this operator)))
153157

154158
(definline realized?
155159
"Returns true if the manifold deferred is realized."
@@ -1617,7 +1621,9 @@
16171621
(def ^:private then-handle-async (async-for then-handle))
16181622

16191623

1620-
1624+
(defn- then-exceptionally [this ^java.util.function.Function operator]
1625+
(assert-some operator)
1626+
(catch this #(.apply operator %)))
16211627

16221628
;;;
16231629

test/manifold/deferred_stage_test.clj

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,11 +420,37 @@
420420
(let [ex (RuntimeException.)
421421
d1 ^CompletionStage (d/error-deferred ex)
422422
d2 (.handleAsync d1 (fn->BiFunction
423-
(fn [x error]
423+
(fn [x ^Throwable error]
424424
(is (nil? x))
425-
(is (#{ex (.getCause ex)} error))
425+
(is (#{error (.getCause error)} ex))
426426
2
427427
)))]
428428

429429
(is (thrown? RuntimeException @d1))
430430
(is (= 2 @d2)))))
431+
432+
(deftest test-exceptionally
433+
(testing ".exceptionally success"
434+
(let [d1 ^CompletionStage (d/success-deferred 1)
435+
d2 (.exceptionally
436+
d1
437+
(fn->Function
438+
(fn [_]
439+
(throw (RuntimeException.
440+
"This should not run")))))]
441+
442+
(is (= 1 @d1))
443+
(is (= 1 @d2))))
444+
445+
(testing ".exceptionally failure"
446+
(let [base-error (RuntimeException.)
447+
d1 ^CompletionStage (d/error-deferred base-error)
448+
d2 (.exceptionally
449+
d1
450+
(fn->Function
451+
(fn [^Throwable error]
452+
(is (#{error (.getCause error)} base-error))
453+
2)))]
454+
455+
(is (thrown? RuntimeException @d1))
456+
(is (= 2 @d2)))))

0 commit comments

Comments
 (0)