mirror of https://github.com/status-im/reagent.git
Improve exception-handling in reactions
Make sure exceptions in children of reactions don't end up being caught in the reaction itself.
This commit is contained in:
parent
e31c72670c
commit
e128117788
|
@ -140,7 +140,7 @@
|
|||
(if (nil? rat)
|
||||
(ratom/run-in-reaction #(do-render c) c "cljsRatom"
|
||||
batch/queue-render rat-opts)
|
||||
(._run rat))))))})
|
||||
(._run rat false))))))})
|
||||
|
||||
(defn custom-wrapper [key f]
|
||||
(case key
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
(when-not (nil? q)
|
||||
(set! rea-queue nil)
|
||||
(dotimes [i (alength q)]
|
||||
(._try-run (aget q i)))
|
||||
(._queued-run (aget q i)))
|
||||
(recur)))))
|
||||
|
||||
(set! batch/ratom-flush flush!)
|
||||
|
@ -379,7 +379,7 @@
|
|||
(set! dirty? true)
|
||||
(rea-enqueue this))
|
||||
(if (true? auto-run)
|
||||
(._run this)
|
||||
(._run this false)
|
||||
(auto-run this)))))
|
||||
|
||||
(_update-watching [this derefed]
|
||||
|
@ -391,20 +391,24 @@
|
|||
(doseq [w (s/difference old new)]
|
||||
(-remove-watch w this))))
|
||||
|
||||
(_try-run [this]
|
||||
(_queued-run [this]
|
||||
(when (and dirty? (some? watching))
|
||||
(try
|
||||
(set! caught nil)
|
||||
(._run this)
|
||||
(catch :default e
|
||||
(set! state e)
|
||||
(set! caught e)
|
||||
(set! dirty? false)
|
||||
(notify-w this e nil)))))
|
||||
(._run this true)))
|
||||
|
||||
(_run [this]
|
||||
(_try-capture [this f]
|
||||
(try
|
||||
(set! caught nil)
|
||||
(deref-capture f this)
|
||||
(catch :default e
|
||||
(set! state e)
|
||||
(set! caught e)
|
||||
(set! dirty? false))))
|
||||
|
||||
(_run [this check]
|
||||
(let [oldstate state
|
||||
res (deref-capture f this)]
|
||||
res (if check
|
||||
(._try-capture this f)
|
||||
(deref-capture f this))]
|
||||
(when-not nocache?
|
||||
(set! state res)
|
||||
;; Use = to determine equality from reactions, since
|
||||
|
@ -427,7 +431,7 @@
|
|||
IRunnable
|
||||
(run [this]
|
||||
(flush!)
|
||||
(._run this))
|
||||
(._run this false))
|
||||
|
||||
IDeref
|
||||
(-deref [this]
|
||||
|
@ -445,7 +449,7 @@
|
|||
(do
|
||||
(notify-deref-watcher! this)
|
||||
(when dirty?
|
||||
(._run this)))))
|
||||
(._run this false)))))
|
||||
state)
|
||||
|
||||
IDisposable
|
||||
|
|
|
@ -371,3 +371,41 @@
|
|||
(is (= @count 3))
|
||||
(dispose r)
|
||||
(is (= runs (running)))))
|
||||
|
||||
(deftest exception-side-effect
|
||||
(let [runs (running)
|
||||
state (r/atom {:val 1})
|
||||
rstate (reaction @state)
|
||||
spy (atom nil)
|
||||
r1 (run! @rstate)
|
||||
r2 (let [val (reaction (:val @rstate))]
|
||||
(run!
|
||||
(reset! spy @val)
|
||||
(is (some? @val))))
|
||||
r3 (run!
|
||||
(when (:error? @rstate)
|
||||
(throw (js/Error. "Error detected!"))))]
|
||||
(swap! state assoc :val 2)
|
||||
(r/flush)
|
||||
(swap! state assoc :error? true)
|
||||
(is (thrown? :default (r/flush)))
|
||||
(r/flush)
|
||||
(r/flush)
|
||||
(dispose r1)
|
||||
(dispose r2)
|
||||
(dispose r3)
|
||||
(is (= runs (running)))))
|
||||
|
||||
(deftest exception-reporting
|
||||
(let [runs (running)
|
||||
state (r/atom {:val 1})
|
||||
rstate (reaction (:val @state))
|
||||
r1 (run!
|
||||
(assert (not= @rstate 13) "fail"))]
|
||||
(swap! state assoc :val 13)
|
||||
(is (thrown? :default
|
||||
(r/flush)))
|
||||
(swap! state assoc :val 2)
|
||||
(r/flush)
|
||||
(dispose r1)
|
||||
(is (= runs (running)))))
|
||||
|
|
Loading…
Reference in New Issue