Fork me on GitHub

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.)


do you have an example stack trace?


@enn unfortunately errors during accumulation aren’t handled as well as errors in non-accumulator conditions; is logged to improve that (non-accumulator conditions were improved in )


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


Your stacktrace tells me you’re throwing in the reduce-fn


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


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, you can also look at the structures created at


Thank you, the wrapping idea makes sense


though a little clunky as we are not specifying the reduce-fn directly (it’s created via acc/max and comparison-based)


Yeah, it is clunky, but hopefully if you have just a handful of rules and a particular exception it won’t be too bad. Obviously not as nice as having built-in error handling i.e. issue 265 but hopefully solves your immediate need