(set-error-handler! a handler-fn)
Sets the error-handler of agent a to handler-fn. If an action being run by the agent throws an exception or doesn't pass the validator fn, handler-fn will be called with two arguments: the agent and the exception.
(def bond (agent 7))
(defn err-handler-fn [ag ex]
(println "evil error occured: " ex " and we still have value " @ag))
(set-error-handler! bond err-handler-fn)
;;division by zero:
(send bond (fn [x] (/ x 0)))
=>evil error occured: #<ArithmeticException java.lang.ArithmeticException:
=>Divide by zero> and we still have value 7
(send bond inc)
=>FAILURE ;;Agent is failed, needs restart, but keeps the last OK value
@bond
=>7
(restart-agent bond 7) ;; or replace 7 with @ag
(send bond inc)
=>#<Agent@88d00c6: 7> ;;because of async update
@bond
=>8
(deftest t-rstart
(future (println "running in a thread..."))
(let [agt (agent 0)
; This doesn't work
h01 (fn [a e]
(println :10 "agent error found:" )
(println :11 "restarting agent...")
(restart-agent a 100)
(Thread/sleep 100)
(println :12 "agent restarted, state=" @a))
; This works. Need to call restart-agent in a separate thread
h02 (fn [a e]
(println :20 "agent error found:" )
(future
(println :21 "restarting agent...")
(restart-agent a 200)
(println :22 "agent restarted, state=" @a))) ;=> 200
]
(set-error-handler! agt h02)
(send agt inc)
(Thread/sleep 100) (println :01 @agt) ;=> 1
(Thread/sleep 100) (send agt #(/ % 0))
(Thread/sleep 100) (println :02 @agt) ;=> 200
(Thread/sleep 100) (send agt inc)
(Thread/sleep 100) (println :03 @agt) ;=> 201
))
; Output
; running in a thread...
; :01 1
; :20 agent error found:
; :21 restarting agent...
; :22 agent restarted, state= 200
; :02 200
; :03 201