0
votes

I am inserting multiple facts to the drools session and calling the fireAllRules on the session. If any one facts fails an exception is thrown and the rule is not executed for the remaining facts.

My question is:

  1. Is there a way to continue executing remaining facts even if one fact failed?
  2. Is there a way to know the facts which failed among the multiple facts inserted to the session?

//My scala code snippet:

val ruleSession:KieSession = kBase.newKieSession();

ruleSession.insert(fact1);
ruleSession.insert(fact2);
ruleSession.insert(fact3);

ruleSession.fireAllRules()
ruleSession.dispose()

Let me know any helpful thoughts. Thanks

2
Does this answer your question? Exception handling at individual rule level - DroolsProg_G
Don't throw an exception.Roddy of the Frozen Peas
Let me try using ConsequenceExceptionHandler and see if I can get the fact which failed, I will update here. Thanks for the link.Biju Gopinathan
@Prog_G , Thank you so much for sharing the link , using the ConsequenceExceptionHandler got my job done, I will share my sample code below as an answer as the use case is different from the one in the link. Appreciate your help.Biju Gopinathan

2 Answers

0
votes

As the above link in the comment(by Prog_G) says I implemented the ConsequenceExceptionHandler and handled the exception gracefully in the handleException method, I logged the failed fact and removed it from executing the further rules, sample code is given below. Hope this help someone having similar use cases.

//Drools Session creation

KieBaseConfiguration kconfig = new RuleBaseConfiguration();
kconfig.setProperty(ConsequenceExceptionHandlerOption.PROPERTY_NAME, "com.xxx.RuleExceptionHandler"); // set my exception handler name to RuleBaseConfiguration
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieBase kieBase = kContainer.newKieBase("ims-hw-rules",kconfig); // create KieBase passing the config
KieSession kSession = kieBase.newKieSession();

//ConsequenceExceptionHandler Implementation.

public class RuleExceptionHandler implements ConsequenceExceptionHandler{
    @Override
    public void handleException(Match match, RuleRuntime workingMemory, Exception exception) {

        //if(exception instanceof MyException) {
            if(match.getObjects().size() >0) {
                for (Object object : match.getObjects()) {
                    JSONData fact = (JSONData) object;
                    //logFailedFact(fact);
                }
            }

            if(match.getFactHandles()!= null) {
                for (FactHandle factHandle : match.getFactHandles()) {
                    workingMemory.delete(factHandle); // delete the failed fact from executing remaining rules.
                }
            }
        //}
    }
}
0
votes

This should fit first requirement.

val ruleSession:KieSession = kBase.newKieSession();

ruleSession.insert(fact1);
ruleSession.fireAllRules()

ruleSession.insert(fact2);
ruleSession.fireAllRules()

ruleSession.insert(fact3);
ruleSession.fireAllRules()

ruleSession.dispose()