From a5c5e1831f66c7e046ed56310bca0c7dd2f293cf Mon Sep 17 00:00:00 2001 From: Bruce Hauman Date: Tue, 20 Nov 2018 08:55:31 -0500 Subject: [PATCH] better protect transaction history polling from errors Go blocks parse try catch blocks and turn them into event dispatches. This captures the original intent of the code to catch errors and terminate the current async worker execution. Signed-off-by: yenda --- src/status_im/models/transactions.cljs | 25 +++++++++++++------ .../status_im/test/wallet/transactions.cljs | 2 +- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/status_im/models/transactions.cljs b/src/status_im/models/transactions.cljs index e01196eb07..539d47fad4 100644 --- a/src/status_im/models/transactions.cljs +++ b/src/status_im/models/transactions.cljs @@ -254,14 +254,23 @@ (defn- async-periodic-exec "Periodically execute an function. + Takes a work-fn of one argument `finished-fn -> any` this function is passed a finished-fn that must be called to signal that the work being performed in the work-fn is finished. - The work-fn can be forced to run immediately " + Returns a go channel that represents a way to control the looping process. + + Stop the polling loop with `async-periodic-stop!` + + The work-fn can be forced to run immediately with `async-periodic-run!` + + Or you can queue up another fn `finished-fn -> any` to execute on + the queue with `async-periodic-run!`." [work-fn interval-ms timeout-ms] {:pre [(fn? work-fn) (integer? interval-ms) (integer? timeout-ms)]} - (let [do-now-chan (async/chan (async/sliding-buffer 1))] + (let [do-now-chan (async/chan (async/sliding-buffer 1)) + try-it (fn [exec-fn catch-fn] (try (exec-fn) (catch :default e (catch-fn e))))] (go-loop [] (let [timeout (async-util/timeout interval-ms) finished-chan (async/promise-chan) @@ -269,12 +278,12 @@ worker (if (and (= ch do-now-chan) (fn? v)) v work-fn)] (when-not (and (= ch do-now-chan) (nil? v)) - (try - (worker #(async/put! finished-chan true)) - ;; if an error occurs in work-fn log it and consider it done - (catch :default e - (log/error "failed to run transaction sync" e) - (async/put! finished-chan true))) + ;; don't let try catch be parsed by go-block + (try-it #(worker (fn [] (async/put! finished-chan true))) + (fn [e] + (log/error "failed to run transaction sync" e) + ;; if an error occurs in work-fn log it and consider it done + (async/put! finished-chan true))) ;; sanity timeout for work-fn (async/alts! [finished-chan (async-util/timeout timeout-ms)]) (recur)))) diff --git a/test/cljs/status_im/test/wallet/transactions.cljs b/test/cljs/status_im/test/wallet/transactions.cljs index c0ee174804..789b788b32 100644 --- a/test/cljs/status_im/test/wallet/transactions.cljs +++ b/test/cljs/status_im/test/wallet/transactions.cljs @@ -104,7 +104,7 @@ (swap! state inc) (throw (ex-info "Throwing this on purpose in error-in-job test" {}))) 10 - 10)) + 100)) (async test-done (js/setTimeout (fn []