Program rule delays Sending message when a condition met

I am currently managing a basic event program that is still in the process of being developed. I have implemented a straightforward program rule that relies on Yes/No data elements. Whenever the condition is met and recorded as “Yes,” the system should send a message to a specific group within DHIS2. Strangely, when data is initially captured and saved for the first time, no message is sent. However, if you return to the data later, make edits, and save it again, the message will be successfully delivered to all groups.

I am using DHIS2 version 2.40.1, and Capture version 100.44.6.

I have attached an error for your reference.

  • INFO 2023-11-18T18:28:58,404 TRACKER_IMPORT_JOB ( VlO15X0DZMH ) finished in 0.113144 sec. Import:Done (NotificationLoggerUtil.java [http-nio-8086-exec-10]) ID1A3doF8fmClrh9tcdPBbKxfATxXtgK51IXEOiAj9erU=
  • INFO 2023-11-18T18:28:58,411 Tracker Rule-engine side effects completed (NotificationLoggerUtil.java [taskScheduler-1])
  • ERROR 2023-11-18T18:28:58,412 Unexpected exception occurred invoking async method: public void org.hisp.dhis.program.notification.ProgramNotificationListener.onProgramRuleEvent(org.hisp.dhis.program.notification.event.ProgramRuleStageEvent) (SimpleAsyncUncaughtExceptionHandler.java [SimpleAsyncTaskExecutor-467])
    java.lang.NullPointerException: null
    at org.hisp.dhis.notification.ProgramStageNotificationMessageRenderer.resolveDataElementValues(ProgramStageNotificationMessageRenderer.java:157) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.notification.ProgramStageNotificationMessageRenderer.resolveDataElementValues(ProgramStageNotificationMessageRenderer.java:49) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.notification.BaseNotificationMessageRenderer.lambda$new$2(BaseNotificationMessageRenderer.java:100) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.notification.BaseNotificationMessageRenderer.resolveValuesFromExpressions(BaseNotificationMessageRenderer.java:194) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.notification.BaseNotificationMessageRenderer.lambda$render$3(BaseNotificationMessageRenderer.java:136) ~[dhis-service-core-2.40.1.jar:?]
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[?:?]
    at java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1764) ~[?:?]
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[?:?]
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[?:?]
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[?:?]
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?]
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:589) ~[?:?]
    at org.hisp.dhis.notification.BaseNotificationMessageRenderer.render(BaseNotificationMessageRenderer.java:137) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.program.notification.DefaultProgramNotificationService.createDhisMessage(DefaultProgramNotificationService.java:611) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.program.notification.DefaultProgramNotificationService.lambda$createProgramStageInstanceMessageBatch$13(DefaultProgramNotificationService.java:404) ~[dhis-service-core-2.40.1.jar:?]
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[?:?]
    at java.util.Collections$2.tryAdvance(Collections.java:4747) ~[?:?]
    at java.util.Collections$2.forEachRemaining(Collections.java:4755) ~[?:?]
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[?:?]
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[?:?]
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[?:?]
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?]
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[?:?]
    at org.hisp.dhis.program.notification.DefaultProgramNotificationService.createProgramStageInstanceMessageBatch(DefaultProgramNotificationService.java:405) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.program.notification.DefaultProgramNotificationService.sendProgramRuleTriggeredEventNotifications(DefaultProgramNotificationService.java:326) ~[dhis-service-core-2.40.1.jar:?]
    at jdk.internal.reflect.GeneratedMethodAccessor3423.invoke(Unknown Source) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.29.jar:5.3.29]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.29.jar:5.3.29]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:241) ~[spring-aop-5.3.29.jar:5.3.29]
    at com.sun.proxy.$Proxy397.sendProgramRuleTriggeredEventNotifications(Unknown Source) ~[?:?]
    at org.hisp.dhis.program.notification.ProgramNotificationListener.onProgramRuleEvent(ProgramNotificationListener.java:75) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.program.notification.ProgramNotificationListener$$FastClassBySpringCGLIB$$dcce2ca4.invoke() ~[dhis-service-core-2.40.1.jar:?]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) ~[spring-aop-5.3.29.jar:5.3.29]
    at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
    at java.lang.Thread.run(Thread.java:829) [?:?]
  • ERROR 2023-11-18T18:28:58,412 Unexpected exception occurred invoking async method: public void org.hisp.dhis.program.notification.ProgramNotificationListener.onProgramRuleEvent(org.hisp.dhis.program.notification.event.ProgramRuleStageEvent) (SimpleAsyncUncaughtExceptionHandler.java [SimpleAsyncTaskExecutor-468])
    java.lang.NullPointerException: null
    at org.hisp.dhis.notification.ProgramStageNotificationMessageRenderer.resolveDataElementValues(ProgramStageNotificationMessageRenderer.java:157) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.notification.ProgramStageNotificationMessageRenderer.resolveDataElementValues(ProgramStageNotificationMessageRenderer.java:49) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.notification.BaseNotificationMessageRenderer.lambda$new$2(BaseNotificationMessageRenderer.java:100) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.notification.BaseNotificationMessageRenderer.resolveValuesFromExpressions(BaseNotificationMessageRenderer.java:194) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.notification.BaseNotificationMessageRenderer.lambda$render$3(BaseNotificationMessageRenderer.java:136) ~[dhis-service-core-2.40.1.jar:?]
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[?:?]
    at java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1764) ~[?:?]
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[?:?]
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[?:?]
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[?:?]
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?]
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:589) ~[?:?]
    at org.hisp.dhis.notification.BaseNotificationMessageRenderer.render(BaseNotificationMessageRenderer.java:137) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.program.notification.DefaultProgramNotificationService.createDhisMessage(DefaultProgramNotificationService.java:611) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.program.notification.DefaultProgramNotificationService.lambda$createProgramStageInstanceMessageBatch$13(DefaultProgramNotificationService.java:404) ~[dhis-service-core-2.40.1.jar:?]
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[?:?]
    at java.util.Collections$2.tryAdvance(Collections.java:4747) ~[?:?]
    at java.util.Collections$2.forEachRemaining(Collections.java:4755) ~[?:?]
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[?:?]
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[?:?]
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[?:?]
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?]
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[?:?]
    at org.hisp.dhis.program.notification.DefaultProgramNotificationService.createProgramStageInstanceMessageBatch(DefaultProgramNotificationService.java:405) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.program.notification.DefaultProgramNotificationService.sendProgramRuleTriggeredEventNotifications(DefaultProgramNotificationService.java:326) ~[dhis-service-core-2.40.1.jar:?]
    at jdk.internal.reflect.GeneratedMethodAccessor3423.invoke(Unknown Source) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.29.jar:5.3.29]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.29.jar:5.3.29]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:241) ~[spring-aop-5.3.29.jar:5.3.29]
    at com.sun.proxy.$Proxy397.sendProgramRuleTriggeredEventNotifications(Unknown Source) ~[?:?]
    at org.hisp.dhis.program.notification.ProgramNotificationListener.onProgramRuleEvent(ProgramNotificationListener.java:75) ~[dhis-service-core-2.40.1.jar:?]
    at org.hisp.dhis.program.notification.ProgramNotificationListener$$FastClassBySpringCGLIB$$dcce2ca4.invoke() ~[dhis-service-core-2.40.1.jar:?]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.29.jar:5.3.29]
    at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) ~[spring-aop-5.3.29.jar:5.3.29]
    at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
    at java.lang.Thread.run(Thread.java:829) [?:?]
1 Like

Hi @sele

Based on the info and the errors in the log, it appears that the program rule is running successfully; however, the first time it runs there are null values and thus it doesn’t run again. It should be configured so that it is only triggered after all the values are recorded.

It would help if you could share the metadata configuration for this program rule. Additionally, one way to test and see how this is working is by changing the action from ‘sending message’ to ‘showing error/warning message’. The error/warning message should appear as soon as the program rule is triggered and if it triggers before it is supposed to then you’d be able to add more conditions ensuring that it triggers when it is ready. Hopefully, the message will also show if there are null values but it might need to be edited and repurposed temporarily for testing…

I hope this helps! Thanks!