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