Page 1 of 1

Logging of variable

Posted: Fri Sep 08, 2023 11:30 am
by JimmyHartington
Hi

I have made a small script, which takes an URL and encodes it with "encodeURI". See code below.
It fails if I try to log the encoded URL.
If I do no logging it works and sets the private data correctly.

I get this error:

Code: Select all

Invalid placeholders in log message
    at Object._0x4028cb [as _log] (C:\Program Files\Enfocus\Enfocus Switch\ScriptExecutor\nodemodules\node_modules\switch-scripting\index.js:727:23)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async _0x48bf25.log (C:\Program Files\Enfocus\Enfocus Switch\ScriptExecutor\nodemodules\node_modules\switch-scripting\index.js:2735:17)
    at async jobArrived (D:\Switch-Scripts\EncodeURL\main.js:1:982)
    at async _0x45c618 (C:\Program Files\Enfocus\Enfocus Switch\ScriptExecutor\nodemodules\node_modules\switch-scripting\index.js:1278:28)
    at async D:\Switch-Scripts\EncodeURL\main.js:1:3352
In this test, the encoded URL is set to "https://www.skabertrang.dk/en%20lille%20test".

Should the log not be able to show this?

Code: Select all

async function jobArrived(s: Switch, flowElement: FlowElement, job: Job) {

    let URLtoEncode: string = await flowElement.getPropertyStringValue("URLtoEncode") as string;
    let PDKey: string = await flowElement.getPropertyStringValue("PDKey") as string;

// Encode complete URL
let encodedURL: string = await encodeURI(URLtoEncode) as string;

await job.log(LogLevel.Info, "URL to encode: \"" + URLtoEncode + "\"");

await job.log(LogLevel.Info, "Encoded URL: \"" + encodedURL + "\"");

await job.setPrivateData(PDKey, encodedURL);

await job.sendToData(Connection.Level.Success);
}

Re: Logging of variable

Posted: Fri Sep 08, 2023 12:54 pm
by foxpalace
Hi

Code: Select all

await job.log(LogLevel.Info, "Url to encode: " + URLtoEncode);

Re: Logging of variable

Posted: Fri Sep 08, 2023 1:06 pm
by patej
Hi,
This is due to Switch reading the %2 from your string and interpreting that the log message includes a placeholder (%1, %2 etc) to replace like you could use it await jog.log(LogLevel.Info, 'Message about %1',[jobName]); <–– here the %1 is replaced with jobName variable.

So you can get around this by using a variable:

Code: Select all

await job.log(LogLevel.Info,'Encoded URL: "%1"',[URLtoEncode]);
or by replacing the %20 with a space in the message:

Code: Select all

await job.log(LogLevel.Info,`Encoded URL: "${URLtoEncode.replace(/%20/g,' ')}"`);

Re: Logging of variable

Posted: Fri Sep 08, 2023 1:32 pm
by freddyp
The reason that the logging of an encoded URL does not work hangs together with the way in which the logging works. If you look at the documentation you will see that the log method takes 3 parameters: a log level, a log string and an array of strings for replacement in the log string:

Code: Select all

let replacements = ["abc", "def"];
await job.log(LogLevel.Info, "This is value 1: %1. And this is value 2: %2.", replacements);
will log
This is value 1: abc. And this is value 2: def.

Many would write this as:

Code: Select all

let replacements = ["abc", "def"];
await job.log(LogLevel.Info, "This is value 1: " + replacements[0] + ". And this is value 2: " + replacements[1]+ ".";
and that wil log exactly the same.

Now consider string translations. The second method is problematic because the part of the log string that requires translation is split over two different strings. With the first method that is not the case: you translate 1 string with the %n in the right place and that is it. That is the background on why this is the way it is.

An unfortunate side effect is that the % sign is also used in URL encoding. That was not a consideration when the above method was chosen many years ago. Today another replacement character would have been chosen. So, if your encoded URL contains %20 the Switch logging mechanism wants to replace the %2 by the second element in the array of strings of the third parameters, but in your case there is no third parameter and it fails.

As a workaround you can do the following:

Code: Select all

let replacements = ["%1", "%2", "%3", "%4", "%5", "%6", "%7", "%8", "%9"];
await job.log(LogLevel.Info, encodedURL, replacements);

Re: Logging of variable

Posted: Fri Sep 08, 2023 1:48 pm
by JimmyHartington
freddyp wrote: Fri Sep 08, 2023 1:32 pm As a workaround you can do the following:

Code: Select all

let replacements = ["%1", "%2", "%3", "%4", "%5", "%6", "%7", "%8", "%9"];
await job.log(LogLevel.Info, encodedURL, replacements);
I tried to add this code to the script.
But it gives the same error.

Since the logging works this way, I think I will just not log this info.

Re: Logging of variable

Posted: Fri Sep 08, 2023 1:51 pm
by patej
JimmyHartington wrote: Fri Sep 08, 2023 1:48 pm
freddyp wrote: Fri Sep 08, 2023 1:32 pm As a workaround you can do the following:

Code: Select all

let replacements = ["%1", "%2", "%3", "%4", "%5", "%6", "%7", "%8", "%9"];
await job.log(LogLevel.Info, encodedURL, replacements);
I tried to add this code to the script.
But it gives the same error.

Since the logging works this way, I think I will just not log this info.
Did you try my suggestions above? I tested only in a script expression, but both work there:
Image

Re: Logging of variable

Posted: Fri Sep 08, 2023 1:52 pm
by JimmyHartington
patej wrote: Fri Sep 08, 2023 1:06 pm So you can get around this by using a variable:

Code: Select all

await job.log(LogLevel.Info,'Encoded URL: "%1"',[URLtoEncode]);
Thanks patej.
This method works.

Code: Select all

await job.log(LogLevel.Info,'Encoded URL: "%1"',[encodedURL]);
Image

So now the finished code is like this:

Code: Select all

async function jobArrived(s: Switch, flowElement: FlowElement, job: Job) {

    let URLtoEncode: string = await flowElement.getPropertyStringValue("URLtoEncode") as string;
    let PDKey: string = await flowElement.getPropertyStringValue("PDKey") as string;

    // Encode complete URL
    let encodedURL: string = await encodeURI(URLtoEncode) as string;

    await job.log(LogLevel.Info, 'URL to encode: "%1"', [URLtoEncode]);

    await job.log(LogLevel.Info, 'Encoded URL: "%1"', [encodedURL]);

    await job.setPrivateData(PDKey, encodedURL);

    await job.log(LogLevel.Info, 'Private Data Key "%1" set to "%2"', [PDKey, encodedURL]);

    await job.sendToData(Connection.Level.Success);
}