Search code examples
node.jslinuxpuppeteerchrome-devtools-protocolchrome-remote-debugging

NodeJS - Error: connect ECONNREFUSED 127.0.0.1:port (chrome-remote-interface)


I made a script using chrome-launcher and chrome-remote-interface to save a webpage to pdf using Chrome.

It works without any issue on my Windows machine, but when I try it on CentOS 7, I obtain the following error and I can't figure out why. Both use Chrome v86.

On Windows I use NodeJS v12.18.4 On Linux I tried both v15.1 and v12.19

SELinux status: disabled

I tried to check if other applications were using the port in the error and there weren't any.

node:internal/process/promises:218
    triggerUncaughtException(err, true /* fromPromise */);
    ^

Error: connect ECONNREFUSED 127.0.0.1:43265
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1128:16) {
  errno: -111,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 43265
}

My code:

const chromeLauncher = require('chrome-launcher');
const CDP = require('chrome-remote-interface');
const file = require('fs');
var check = 1;

(async function() {
  async function launchChrome() {
    return await chromeLauncher.launch({
      chromeFlags: [
        '--no-first-run',
        '--headless',
        '--disable-gpu'
      ]
    });
  }

  const chrome = await launchChrome();
  const protocol = await CDP({
    port: chrome.port
  });

  const {
    DOM,
    Page,
    Emulation,
    Runtime
  } = protocol;

  await Promise.all([
    Page.enable(),
    Runtime.enable(),
    DOM.enable()
  ]);

  const {
    frameId
  } = await Page.navigate({
    url: 'https://url/'
  });
  await Page.loadEventFired();
  const script1 = "window.status";
  while (check) {
    var result = await Runtime.evaluate({
      expression: script1
    });
    if (result.result.value == 'ready_to_print') {
      check = 0;
    }
  }

  let {
    data
  } = await Page.printToPDF({
    landscape: false,
    printBackground: true,
    scale: 0.7
  });

  file.writeFile('print.pdf', Buffer.from(data, 'base64'), 'base64', function(err) {
    if (err) {
      console.log(err);
    }

    protocol.close();
    chrome.kill();
  });
})();

If you have alternative ways using Chrome and scaling to 0.7, let me know.

Thanks


Solution

  • I tried to use the launchChrome() function by itself and found that it was the issue. After some research I found the solution. I had to add '--no-sandbox' in the chromeLauncher.launch flags.

    Here the fully working code:

    const chromeLauncher = require('chrome-launcher');
    const CDP = require('chrome-remote-interface');
    const file = require('fs');
    var check = 1;
    
    (async function() {
        async function launchChrome() {
          return await chromeLauncher.launch({
            chromeFlags: [
              '--no-first-run',
              '--headless',
              '--disable-gpu',
              '--no-sandbox'
            ]
          });
        }
    
        const chrome = await launchChrome();
        const protocol = await CDP({
          port: chrome.port
        });
    
        const { DOM, Page, Emulation, Runtime } = protocol;
    
        await Promise.all([
          Page.enable(),
          Runtime.enable(),
          DOM.enable()
        ]);
    
        const { frameId } = await Page.navigate({ url: 'https://url/' });
        await Page.loadEventFired();
        const script1 = "window.status";
        while(check){
            var result = await Runtime.evaluate({
                expression: script1
            });
            if(result.result.value=='ready_to_print'){
                check = 0;
            }
        }
    
        let { data } = await Page.printToPDF({
          landscape: false,
          printBackground: true,
          scale: 0.7
        });
    
        file.writeFile('print.pdf', Buffer.from(data, 'base64'), 'base64', function(err) {
          if (err) {
            console.log(err);
          }
    
          protocol.close();
          chrome.kill();
        });
      })();