Getting TypeError when running JS transform in script

Platform information:

##   Release = Debian GNU/Linux 12 (bookworm)
##    Kernel = Linux 6.1.0-10-amd64
##  Platform = VMware Virtual Platform/440BX Desktop Reference Platform
##    Uptime = 17 day(s). 23:30:57
## CPU Usage = 0% avg over 2 cpu(s) (1 core(s) x 2 socket(s))
##  CPU Load = 1m: 0.00, 5m: 0.01, 15m: 0.00
##    Memory = Free: 0.14GB (4%), Used: 3.93GB (96%), Total: 3.82GB
##      Swap = Free: 0.95GB (100%), Used: 0.00GB (0%), Total: 0.95GB
##      Root = Free: 10.13GB (72%), Used: 3.80GB (28%), Total: 14.70GB
##   Updates = 14 apt updates available.
##  Sessions = 1 session(s)
## Processes = 192 running processes of 4194304 maximum processes
## openHAB 4.0.2 - Release Build

Issue of the topic: please be detailed explaining your issue

I have a network player that I’ve been struggling to control for the last several years. I’m now attempting to see if I can control it via scripts. I’m able to execute commands but I need to parse the payload in order to validate the configuration settings. The payload is xml so I’ve tried using XPATH and REGEX transforms. The XPATH transform works in the thing channels when obtaining status but not for setting the configuration. However, I can’t get the XPATH or the REGEX transform to work in a javascript. I keep getting the following error

org.graalvm.polyglot.PolyglotException: TypeError: Cannot read property "toString" from null

I’ve tried calling the transform function within a script or encapsulating it in a function and calling the function. Each time, I get the same error. I hope someone can help me.

The ECMAScript 262 Edition 11 script I’m using is below.

var HTTP = Java.type("org.openhab.core.model.script.actions.HTTP");
URLCRXN560 = "http://192.168.128.199/YamahaRemoteControl/ctrl";
xmlheader = '{?xml version="1.0" encoding="utf-8"?}';
PowerChk = '{<YAMAHA_AV cmd="GET"><System><Power_Control><Power>GetParam</Power></Power_Control></System></YAMAHA_AV>}';

// Function REGEX transform
function xmlparse (myVariable) {
  return actions.Transformation.transform("REGEX", "(?<=\>)(.*?)(?=\<)", myVariable);
  };

output1=HTTP.sendHttpPostRequest(URLCRXN560,xmlheader,PowerChk);
console.log("Raw Power Response is: ", output1);
console.log("Filtered Power Response is: ", xmlparse(output1));

Do you see the “Raw Power Response is” log statement before that error?

Is this code complete? You’ve not declared URLCRXN560, xmlheader,PowerChk, nor output1 as variables.

Use the standard way to access the action:

var output1 = actions.HTTP.sendHttpPostRequest(...

You should almost never have to have a Java.type in an GraalVM JS script, especially when interacting with openHAB stuff.

var URLCRXN560 = "http://192.168.128.199/YamahaRemoteControl/ctrl";
var xmlheader = '{?xml version="1.0" encoding="utf-8"?}';
var PowerChk = '{<YAMAHA_AV cmd="GET"><System><Power_Control><Power>GetParam</Power></Power_Control></System></YAMAHA_AV>}';

// Function REGEX transform
function xmlparse (myVariable) {
  return actions.Transformation.transform("REGEX", "(?<=\>)(.*?)(?=\<)", myVariable);
};

var output1 = actions.HTTP.sendHttpPostRequest(URLCRXN560, xmlheader, PowerChk);
console.log("Raw Power Response is: ", output1);
console.log("Filtered Power Response is: ", xmlparse(output1));

@rlkoshak, thanks Rich for your response. Yes, I do see the Raw Power Response in the ccnsole. I referenced an old script that was migrated from 3.x to 4.x so I wasn’t aware (my ignorance) of the standard was to access an http action. I did update my script with changes you suggested but I still see the same error.

2023-08-18 10:07:52.421 [INFO ] [tomation.script.ui.yamahaxmlresponse] - Raw Power Response is:  <YAMAHA_AV rsp="GET" RC="0"><System><Power_Control><Power>On</Power></Power_Control></System></YAMAHA_AV>
2023-08-18 10:07:52.423 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: TypeError: Cannot read property "toString" from null
	at <js>.transform(@openhab-globals.js:2) ~[?:?]
	at <js>.xmlparse(<eval>:7) ~[?:?]
	at <js>.:program(<eval>:12) ~[?:?]
... truncated the rest of the log output

The stack traces is always very helpful. In general, don’t redact information. It’s better for us to have too much than not enough.

The stack trace makes it clear that the problem is coming from parsing the XML which means there is something up with your REGEX transformation. I suspect it’s not returning anything and returning null and failing to convert null to a String.

This might be worth an issue on the REGEX transformation to not error like that when there is no match.

Now that we know what line is the error we can see what else might be the problem.
For one, your REGEX is not a proper one for OH. The way that the REGEX transformation works, the expression must match the entire String, newlines and all. In addition, only the first matching group (denoted by ( )) gets returned. ? means 0 or one of the previous but you don’t have a previous pattern where you use it. .*? doesn’t make any sense at all. It means “any character 0 or more times one or more times”.

How did you come up with this REGEX?

Something like the following should work.

".*<Power>(.*)</Power>.*

Wow @rlkoshak, that worked!!! The challenge is that I’m not very fluent in these expressions and I found a regex pattern in my Internet searches that I verified on regex101.com. I did see there were multiple matches on regex validator so I was expecting to get something back. I agree with you that transformation should not error when there is no match. I also experienced the same error when using the XPATH transform. At least now, I understand it is the expression that I need to investigate. I appreciate the help.