Logging of variable

Post Reply
User avatar
JimmyHartington
Advanced member
Posts: 310
Joined: Tue Mar 22, 2011 7:38 am

Logging of variable

Post 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);
}
User avatar
foxpalace
Member
Posts: 33
Joined: Fri Jan 14, 2011 12:25 pm
Location: Germany

Re: Logging of variable

Post by foxpalace »

Hi

Code: Select all

await job.log(LogLevel.Info, "Url to encode: " + URLtoEncode);
patej
Member
Posts: 79
Joined: Sun Nov 25, 2012 12:15 pm

Re: Logging of variable

Post 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,' ')}"`);
freddyp
Advanced member
Posts: 1023
Joined: Thu Feb 09, 2012 3:53 pm

Re: Logging of variable

Post 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);
User avatar
JimmyHartington
Advanced member
Posts: 310
Joined: Tue Mar 22, 2011 7:38 am

Re: Logging of variable

Post 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.
patej
Member
Posts: 79
Joined: Sun Nov 25, 2012 12:15 pm

Re: Logging of variable

Post 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
User avatar
JimmyHartington
Advanced member
Posts: 310
Joined: Tue Mar 22, 2011 7:38 am

Re: Logging of variable

Post 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);
}
Post Reply