Warning in messages of Switch

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

Warning in messages of Switch

Post by JimmyHartington »

I have begun to make more and more scripts with Node.JS.

And often I get this error in the messages of Switch.

Code: Select all

The script execution has ended while an async function or callback in the script might not have finished yet. Please check the script code for unresolved promises or missing await statements.
What is the best way to troubleshoot it?

In this case from the code below.

Code: Select all

// Create PDF using puppeteer (https://pptr.dev) from HTML-file as input
// Jimmy Hartington, Skabertrang, 2024-02-09

import * as fs from "fs";
import * as tmp from "tmp";
import puppeteer from "puppeteer";

async function jobArrived(s: Switch, flowElement: FlowElement, job: Job) {
  // puppeteer
  async function generatePDFfromHTML(document: string, outputPath: string) {
    const browser = await puppeteer.launch({
      args: [
        "--disable-web-security",
        "--disable-features=SameSiteByDefaultCookies,CookiesWithoutSameSiteMustBeSecure",
      ],
    });
    const page = await browser.newPage();
    await page.setUserAgent(
      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
    );
    await page.setContent(document);
    await page.evaluateHandle("document.fonts.ready");
    await page.pdf({ path: outputPath, format: "A4" });
    await browser.close();
  }

  // Usage
  let jobName: string = (await job.getName(false)) as string;
  let jobPath: string = (await job.get(AccessLevel.ReadOnly)) as string;
  let htmlContent = await fs.readFileSync(jobPath, "utf-8");
  const tmpFile: string = await tmp.fileSync({
    prefix: "newfile",
    postfix: ".pdf",
  }).name;

  // puppeteer
  await generatePDFfromHTML(htmlContent, tmpFile)
    .then(() => job.log(LogLevel.Info, "PDF created"))
    .catch((err) => job.log(LogLevel.Error, "Error in creating pdf: " + err));

  let newJob = await job.createChild(tmpFile);
  await newJob.sendToSingle(jobName + ".pdf");

  // delete tmp files
  await fs.unlinkSync(tmpFile);

  // send original to null
  await job.sendToNull();
}

freddyp
Advanced member
Posts: 1023
Joined: Thu Feb 09, 2012 3:53 pm

Re: Warning in messages of Switch

Post by freddyp »

The best way to troubleshoot this is to start a debugging session. As you step through the code you should see what triggers the error. In this case it is pretty easy: you have 2 job.log statements that do not have an await.

I would like to make two side remarks. Everybody has their own coding style so the following is not criticism, but only suggestions that in my opinion increase readability. But again, you may find it to be the contrary.

You define the generatePDFfromHTML function inside the jobArrived function. I would put it at the end. Functions inside functions very quickly blur the overview.

I never use this coding pattern:

Code: Select all

await generatePDFfromHTML(htmlContent, tmpFile)
    .then(() => job.log(LogLevel.Info, "PDF created"))
    .catch((err) => job.log(LogLevel.Error, "Error in creating pdf: " + err));
    
let newJob = await job.createChild(tmpFile);
I use this one:

Code: Select all

try {
    await generatePDFfromHTML(htmlContent, tmpFile);
    job.log(LogLevel.Info, "PDF created"); //it is easier to see the await is missing here
} catch (error) {
    job.log(LogLevel.Error, "Error in creating pdf: " + err)); //same thing
}

let newJob = await job.createChild(tmpFile);
Now it also becomes clearer that your code will continue with createChild in case of an error and that will fail and the temporary file will not get cleaned up. Final version:

Code: Select all

const tmpFile: string = tmp.fileSync({ //putting await everywhere is also not a solution :)
    prefix: "newfile",
    postfix: ".pdf",
  }); //note that I removed .name so I keep the tmp object

try {
    await generatePDFfromHTML(htmlContent, tmpFile.name); //and I have to use .name here then
    await job.log(LogLevel.Info, "PDF created");
} catch (error) {
    job.fail(LogLevel.Error, "Error in creating pdf: " + err)); //job.fail perhaps strangely enough doesn't require await
    tmpFile.removeCallback(); //and now I use the object to remove the temporary file in the correct way
    return;
}

let newJob = await job.createChild(tmpFile);
User avatar
JimmyHartington
Advanced member
Posts: 310
Joined: Tue Mar 22, 2011 7:38 am

Re: Warning in messages of Switch

Post by JimmyHartington »

Thanks for your suggestions in regards to the code.
I do not take it as criticism. I have no formal education in coding, so this is a case of finding a way to convert HTML to PDF and combining the example from the documentation with code from some of my other scripts.

I will try to implement your suggestions.

In regards to debugging, is it possible to run the debug in Visual Studio Code on my mac, when Switch is running in my Windows server?
freddyp
Advanced member
Posts: 1023
Joined: Thu Feb 09, 2012 3:53 pm

Re: Warning in messages of Switch

Post by freddyp »

In regards to debugging, is it possible to run the debug in Visual Studio Code on my mac, when Switch is running in my Windows server?
Remote debugging in VSC is possible (https://learn.microsoft.com/en-us/visua ... ew=vs-2022) but I have never tried it. You will have to do stuff on the Windows server anyhow: stop the flow, activate debugging, activating the flow again and submit a job, modify the code, try again and so. Is it not a lot easier then to do the debugging on the Windows system?
patej
Member
Posts: 79
Joined: Sun Nov 25, 2012 12:15 pm

Re: Warning in messages of Switch

Post by patej »

JimmyHartington wrote: Mon Feb 12, 2024 11:05 am In regards to debugging, is it possible to run the debug in Visual Studio Code on my mac, when Switch is running in my Windows server?
I recommend trying VSCode Remote-SSH extension: https://code.visualstudio.com/docs/remote/ssh We've been using it for over a year now and it has made developing scripts a lot easier when others in the team need to work on the Windows server RDP session. With that, you have access to the Windows file system directly on VSCode on mac and in all other respects it's like working on VSCode on the Windows server, including using terminal to transpile etc. If you're using a version control system, this, compared to working locally on mac, eliminates the need to make unnecessary commits and push–>pull process just to get to test if the code works at all on the server. Only thing that doesn't work on Remote-SSH to Windows servers (unless they've fixed it recently…) is pushing changes to github because for some reason it cannot forward the ssh keys from mac to Windows. But that's a minor downside, because using git naturally works and it's then only the github interaction that has to be done locally on the server.
freddyp wrote: Mon Feb 12, 2024 1:09 pm You will have to do stuff on the Windows server anyhow: stop the flow, activate debugging, activating the flow again and submit a job, modify the code, try again and so. Is it not a lot easier then to do the debugging on the Windows system?
Purely debugging doesn't benefit from the Remote-SSH that much because you have to interact with Switch, too, but when the whole coding process is done using Remote-SSH, debugging with it doesn't make it harder, either :)
Post Reply