Skip to content

Commit ac70775

Browse files
ghaskinsecb
authored andcommitted
Enhance exception handling
Signed-off-by: Greg Haskins <[email protected]>
1 parent dad386a commit ac70775

File tree

6 files changed

+71
-22
lines changed

6 files changed

+71
-22
lines changed

src/temporal/client/core.clj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,10 @@ defworkflow once the workflow concludes.
158158
[{:keys [^WorkflowStub stub] :as workflow}]
159159
(-> (.getResultAsync stub u/bytes-type)
160160
(p/then nippy/thaw)
161-
(p/catch e/slingshot? e/recast-stone)))
161+
(p/catch e/slingshot? e/recast-stone)
162+
(p/catch (fn [e]
163+
(log/error e)
164+
(throw e)))))
162165

163166
(defn query
164167
"

src/temporal/internal/activity.clj

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,9 @@
107107
(log/trace activity-id "calling" f "with args:" a)
108108
(try+
109109
(result-> activity-id (f ctx a))
110-
(catch Exception e
111-
(log/error e)
112-
(throw e))
113110
(catch Object o
114111
(log/error &throw-context)
115-
(e/freeze &throw-context)))))
112+
(e/forward &throw-context)))))
116113

117114
(defn dispatcher [ctx dispatch]
118115
(reify DynamicActivity

src/temporal/internal/exceptions.clj

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
(ns temporal.internal.exceptions
44
(:require [slingshot.slingshot :refer [throw+]]
5+
[taoensso.timbre :as log]
56
[temporal.exceptions :as e]
67
[temporal.internal.utils :as u])
78
(:import [io.temporal.failure ApplicationFailure]))
@@ -12,13 +13,28 @@
1213
(and (instance? ApplicationFailure (ex-cause ex))
1314
(= exception-type (.getType (cast ApplicationFailure (ex-cause ex))))))
1415

15-
(defn freeze
16-
[{{:keys [::e/non-retriable?] :or {non-retriable? false}} :object :as context}]
17-
(let [o (u/->objarray context)
18-
t (if non-retriable?
19-
(ApplicationFailure/newNonRetryableFailure nil exception-type o)
20-
(ApplicationFailure/newFailure nil exception-type o))]
21-
(throw t)))
16+
(defn forward
17+
[{:keys [message wrapper] {:keys [::e/non-retriable?] :or {non-retriable? false} :as object} :object :as context}]
18+
(log/trace "forward:" context)
19+
(cond
20+
(and (map? object) (empty? object) (true? (some->> wrapper (instance? Throwable))))
21+
(do
22+
(log/trace "recasting wrapped exception")
23+
(throw wrapper))
24+
25+
(instance? Throwable object)
26+
(do
27+
(log/trace "recasting throwable")
28+
(throw object))
29+
30+
:else
31+
(do
32+
(log/trace "recasting stone within ApplicationFailure")
33+
(let [o (u/->objarray context)
34+
t (if non-retriable?
35+
(ApplicationFailure/newNonRetryableFailure message exception-type o)
36+
(ApplicationFailure/newFailure message exception-type o))]
37+
(throw t)))))
2238

2339
(defn recast-stone [ex]
2440
(let [stone (->> ex ex-cause (cast ApplicationFailure) (.getDetails) u/->args :object)]

src/temporal/internal/workflow.clj

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,6 @@
6464
(f a))]
6565
(log/trace workflow-id "result:" r)
6666
(nippy/freeze r))
67-
(catch Exception e
68-
(log/error e)
69-
(throw e))
7067
(catch Object o
7168
(log/error &throw-context)
72-
(e/freeze &throw-context))))
69+
(e/forward &throw-context))))

test/temporal/test/exception.clj

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
;; Copyright © Manetu, Inc. All rights reserved
2+
3+
(ns temporal.test.exception
4+
(:require [clojure.test :refer :all]
5+
[taoensso.timbre :as log]
6+
[temporal.client.core :as c]
7+
[temporal.workflow :refer [defworkflow]]
8+
[temporal.activity :refer [defactivity] :as a]
9+
[temporal.test.utils :as t]))
10+
11+
(use-fixtures :once t/wrap-service)
12+
13+
(defactivity exception-activity
14+
[ctx args]
15+
(log/info "exception-activity:" args)
16+
(throw (ex-info "test 1" {})))
17+
18+
(defworkflow indirect-exception-workflow
19+
[args]
20+
(log/info "indirect-exception-workflow:" args)
21+
@(a/invoke exception-activity args {:retry-options {:maximum-attempts 1}}))
22+
23+
(defworkflow direct-exception-workflow
24+
[args]
25+
(log/info "direct-exception-workflow:" args)
26+
(throw (ex-info "test 2" {})))
27+
28+
(deftest the-test
29+
(testing "Verifies that we can throw exceptions indirectly from an activity"
30+
(let [workflow (t/create-workflow indirect-exception-workflow)]
31+
(c/start workflow {})
32+
(is (thrown? Exception @(c/get-result workflow)))))
33+
(testing "Verifies that we can throw exceptions directly from a workflow"
34+
(let [workflow (t/create-workflow direct-exception-workflow)]
35+
(c/start workflow {})
36+
(is (thrown? Exception @(c/get-result workflow))))))

test/temporal/test/slingshot.clj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
(catch [:type ::test1] _
3131
(log/info "caught stone 1")
3232
(try+
33-
@(a/invoke slingshot-retriable-activity args)
33+
@(a/invoke slingshot-retriable-activity args {:retry-options {:maximum-attempts 2}})
3434
(catch [:type ::test2] _
3535
(log/info "caught stone 2")
3636
(throw+ {:type ::test3}))))))
@@ -39,8 +39,8 @@
3939
(testing "Verifies that we can catch slingshot stones across activity/workflow boundaries"
4040
(let [workflow (t/create-workflow slingshot-workflow)]
4141
(c/start workflow {})
42-
(try+
43-
@(c/get-result workflow)
44-
(throw (ex-info "should not get here" {}))
45-
(catch [:type ::test3] _
46-
(log/info "caught stone 3"))))))
42+
(is (= :ok (try+
43+
@(c/get-result workflow)
44+
(throw (ex-info "should not get here" {}))
45+
(catch [:type ::test3] _
46+
:ok)))))))

0 commit comments

Comments
 (0)