In OH 4.0.1 event is always defined. It contains a string like “Timer 6 triggered”, when the rule isn’t triggered by an item but by a timer.
Is this a new feature which is not mentionend in the docs and in the breaking changes? I have to rewrite some of my rules, because I cannot rely on a not defined event object when I want to react to a timer trigger.
Yes. All rule triggers except manually have an event Object telling how the rule was triggered to differentiate between all trigger types, not just Item and Thing triggers.
I don’t know if this made it into the docs. I’m not entirely certain where in the docs it would go.
All you have to change is what you compare to. Instead of if(this.event === undefined) use if(event.type == 'TimerEvent') (I think, log out event.type to verify it’s called “TimerEvent”).
As previously implemented, you couldn’t tell the difference from a timer trigger, a system started trigger, manual trigger, time of day trigger, nor could you tell the difference between timer triggers (the 6 is the ID of the trigger which is shown in the UI under the code tab for UI rules).
That’s a bug then. It should return false if the event is Object is not available. What’s the code generated? It should resolve to (event !== undefined) which will generate false if the event isn’t defined. It shouldn’t throw an error and in my experiements it works as expected.
There might be some strange edge case happening here to generate an error or the error is occuring elsewhere in your rule.
ExecutionEvent when run manually but for some time and I thought it was still the case that when one rule calls another there is no event. At least there isn’t one in a managed Script Action or Script Condition. The event is still there for file based JS rules.
Rules calling other rules are not caused by an event so it seems odd that there would be an event Object. For file based rules though, that’s the only way to get the arguments passed from the other rule unto the action.
But if a rule calling another rule does cause an event now, then there really is no use for the “contextual info event available” block and it should be removed. There will always be an event.
But that still does not explain why it’s throwing an error. It should just always return true.
I guess it’s a matter of perspective or opinion. Rules calling other rules can be considered an execution event. But perhaps it was meant only for when UI rule is executing another script through its rule action?
In any case in JRuby, calling rule["uid"].run, by default will insert an ExecutionEvent (in openhab 4+).
The context is a separate thing outside the event, and it is still needed because ExecutionEvent itself doesn’t carry any context.
This depends on the implementation in the jsscripting library perhaps?
In plain JS, simply calling console.log(test) will generate an exception because test is undefined.
You can only test for undefined when referring to an object’s member.
i.e.:
test => raises an exception (ReferenceError) var x = 0 x.test => doesn’t raise an exception, instead, it would return undefined
The test for event in this case needs to use typeof i.e. if (typeof(event) === undefined). Due to how js does things, this isn’t entirely accurate because one can define var event = undefined but it’s a good enough check.
That’s what is different in JS. For file based rules the action is isolated so all it gets is what’s passed into it. Since JS wraps the event Object anyway to convert it to JS, I added a PR awhile back to include the context as part of that.
For managed rules, the context just gets injected directly and the event Object remains the Java Event and is not wrapped and converted to JS. I very much dislike this difference but it’s technically challenging to overcome so it remains.
Correct. And the “contextual info event available” block turns into (event !== undefined). So no error should be thrown. It doesn’t try to access anything, just see if it exists. That shouldn’t throw an error under any circumstances, just return true or false.
Well of course it’s going to throw an error on that line.
event doesn’t exist, so event.type isn’t going to exist. The whole reason to test if it exists is to not try to use it later because that will throw an error.
That’s because you don’t try to use it after discovering it doesn’t exist like in the first rule.
If exists returns false, you can not do anything with event. If you try it will throw an error.
Rule 2 is triggered by Rule 1 and throws the error… event available → error instead of false (as I would expect)
2025-03-07 22:29:13.071 [ERROR] [.handler.AbstractScriptModuleHandler] - Script execution of rule with UID 'test_blockly_something_else' failed: org.graalvm.polyglot.PolyglotException: ReferenceError: "event" is not defined
It should not throw an error. There is nothing wrong with that code as far as I can tell. event is undefined when it “is not defined”. Maybe the extra pair of parens is causing problems? I can’t imagine why that would be the case.
It’s definitely something strange. All I can offer is to file an issue on Blockly (openhab-webui repo).