Exit rules early in JSRule (ECMA2021)

Hi I’m actually using OH 3.4 stable (debian) with the latest openhab-js updates installed…

While converting my old DSL rules to ECMA2021 I’m facing a problem when trying to exit the rule early.

In Rules DSL I used if statements to do so:

if ("condition is met") return;

but I’m experiencing strange behavior when trying this in a JSRule.

it seems like the rule isn’t exited but instead only the if condition is exited, and the remaining part is still executed.

I read somewhere that in java this should work:

if ("condition is met") rules.exit();

it seems to exit the rule but gives me an error in the logs:

TypeError: rules.exit is not a function

What is actually the best solution for early exiting a JSRule (ECMA2021) correctly?

1 Like

As simple solution you can use a while loop:

while (true) {
// all your stuff
//
if ("condition is met") break;
// all your next stuff
// 
if ("condition is met") break;
// all your next stuff
//
break;
}
1 Like

hi torsten,

just to understand what this does, if I get this right, the while loop is executed until it receives a break command, and finally get’s a break to avoid looping the code, right?

Seems to do what I wanted to achieve… thanks!

I think the way that JS Scripting rules work, it doesn’t support a return statement like you may be used to in Rules DSL.

However, it might support a simple break statement instead (no need for a while loop like @tose shows unless you already have a while loop).

if(condition) break;

I’ve never tested that.

If that doesn’t work, you have options that are better choices than the while(true) option.

  1. Restructure your rule by flipping the condition

    if(!condition) {
    // rule code goes here
    }

When the condition is met the rule does nothing.

  1. wrap the rule’s in a function which lets you exit at will with a return
(function(event) {
    // rule code
    if(condition) return;
})(event)
  1. If running in the UI, put the condition into the Rules “but only if…” section. You may not even need a script if the condition is a simple “if the Item is this state, don’t run the rule”.

I don’t like the while approach because you don’t really have a while loop here and it will raise all sorts of questions for future you about what this code is really doing.

2 Likes

thanks for your additional help!

I’ll try if break; is working - would be the easiest way :wink:

and even to wrap it in a function instead of a while loop, which breaks at the end, looks much cleaner for me…

the inversion of the logic only makes sence when there’s only one condition which exits the rule.

great… if break; is going to work, I’ll post it here as the simpliest solution - we’ll see…