This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-01
Channels
- # beginners (121)
- # boot (12)
- # cider (14)
- # clara (19)
- # cljsjs (1)
- # clojure (124)
- # clojure-italy (4)
- # clojure-nl (2)
- # clojure-russia (47)
- # clojure-spec (20)
- # clojure-uk (7)
- # clojurescript (102)
- # cursive (16)
- # datomic (10)
- # emacs (2)
- # events (2)
- # immutant (3)
- # luminus (5)
- # lumo (33)
- # off-topic (2)
- # om (5)
- # onyx (22)
- # parinfer (1)
- # pedestal (32)
- # protorepl (1)
- # re-frame (6)
- # reagent (2)
- # ring-swagger (2)
- # rum (1)
- # spacemacs (8)
- # specter (17)
- # yada (1)
Can anyone suggest how I might instrument my rules to figure out which one is throwing an NPE?
The NPE is during >
during an accumulator’s reduction which makes me assume it’s the max
accumulator, which I use in only a handful of rules. I’d like to narrow down which specifically is throwing the exception, but I’m not sure how I’d go about putting logging in the LHS of a rule. (The RHS is too late as the accumulators are used only in LHSs.)
ya i got nothing unfortunately. https://github.com/cerner/clara-rules/blob/master/src/main/clojure/clara/tools/tracing.clj might be of some help
@enn unfortunately errors during accumulation aren’t handled as well as errors in non-accumulator conditions; https://github.com/cerner/clara-rules/issues/265 is logged to improve that (non-accumulator conditions were improved in https://github.com/cerner/clara-rules/issues/255 )
In the meantime your best option is probably to wrap the accumulator in question in a way that indicates what rules you’re in when it throw an exception
Clara accumulators are just maps containing functions, and the accumulator can be modified by adding a new value onto one of the keys
So you could do something like (defn ->wrapped-reduce-fn [original-reduce-fn rule-name] (fn [& args] (try (apply original-reduce-fn args) (catch Exception e (throw (ex-info (str “Threw exception in accumulation in ” rule-name) {} e))))
and (defrule [?result-binding <- (update (acc/min :field) :reduce-fn ->wrapped-reduce-fn rule-name) …
actually to work with the update you’d need to reverse the args order of ->wrapped-reduce-fn, but that is the basic idea
The problem with tracing is that when you throw an exception and exit the rules firing loop you’ll lose the transient listener that has the info you want
When a RHS exception is thrown we call to-persistent on the listeners but that won’t happen in an exception during accumulation https://github.com/cerner/clara-rules/blob/master/src/main/clojure/clara/rules/engine.cljc#L1787
You could write your own listener that had global side effects or some such to get around that if you wanted though
There are some docs on what the different accum function fields do at http://www.clara-rules.org/docs/accumulators/, you can also look at the structures created at https://github.com/cerner/clara-rules/blob/master/src/main/clojure/clara/rules/accumulators.cljc