MQTT publish action not available at startup

I rely on MQTT and pushover actions ( publish() and sendPushoverMessage() ) to handle notifications and this is causing issues during system startup because the MQTT action add-on is not already loaded when the ‘System Started’ event is triggered.
Therefore I get the following error message:

2018-09-18 16:50:35.408 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Notify process queue': The name 'publish' cannot be resolved to an item or type; line 189, column 9, length 70

My concern is that I cannot catch the error in my rule so I have no way to catch that the notifications were not sent. I tried:

try{
    publish("myborker", "mychannel" + my_device + "/command", mymessage)
}
catch ( Throwable e) {
    logWarn("Notify process", "publish to MQTT failed: will retry in a while")
}

The logWarn() is never executed and the rule just stops due to the error: the code after the try/catch block is never executed. Any way to catch properly this error?

In particular, this behavior is a problem as this block is intended to run inside a lock() / unlock() sequence and if the rule exits before the unlock(), it will break rule processing.

There is a known bug in OH right now where Rules start executing before everything else in OH is loaded and available. I’ve even seen it complain about stuff like global vals and ON not being defined. There is an issue open.

try/catch inside of Rules can’t catch everything that can go wrong because some exceptions occur in the underlying Rules interpreter kill the Rule so thoroughly as there is no Rule left to roll back down the stack trace. In short, the Rule is gone so the catch is gone so there is nothing there to catch the exception.

This is not true for all errors. It is mainly a problem with type errors and trying to call Actions that don’t exist.

See Cleaning up the startup process / renaming rules (windows possible) for a workaround to address the root cause of the error in this case.

Beyond that, you can schedule the calls to the Actions to occur 30 seconds or so after startup. By that point everything should have settled.

Let’s hope a fix is found soon because the System Started event is useless if it triggers before the system is actually ready.

My current workaround is to design impacted rule to be "unhandled error-proof’ but this complexifies rules logic a lot.

Since you can’t always catch the exception that gets thrown when the error occurs I’m not sure what you will be able to do in the Rule to make it error proof.

Finally, I found a workaround by declaring items to hold the state of Mqtt and Pushover actions, putting them into a SYS_StartComplete group and setting them with CRON during startup.

The .item file:

Group:Switch:AND(ON,OFF)	SYS_StartComplete		"System start complete"	
Switch                      SYS_MQTT_Started		"MQTT started" 	    <automation>	(SYS_StartComplete, System)
Switch                      SYS_Pushover_Started	"Pushover Started" 	<automation>	(SYS_StartComplete, System)

The .rule file

var systemStarted = new Boolean(false)
var mqttStarted  = new Boolean(false)

rule "Notify OpenHAB started"
when
	System started 
then
    if(! systemStarted){
        systemStarted = true
        if(! mqttStarted) {SYS_MQTT_Started.postUpdate(OFF)}
    }
end

rule "Monitor MQTT action addon"
when
	Time cron "0/10 * * * * ?"
then
    if(! mqttStarted){
        try {
            publish("mybroker", "mydummychannel", "0")
        }
        finally {
            mqttStarted = true
            SYS_MQTT_Started.postUpdate(ON)
        }
    }
end	

rule "System start complete (push notification)"
when
	Item SYS_StartComplete changed to ON 
then
    SYS_Notification.sendCommand('Open HAB is actually started' + ';0;16;1;;;;')
end