node.jsdockerexpressaxiosweasyprint

Axios - Getting socket hang up error while generating pdf from wesayprint rest container


I have set up weasyprint rest container to convert html to pdf.

Here is the code in nodejs to call weasyprint api to create pdf,

const axios = require('axios');
const FormData = require("form-data");
const data = new FormData();

data.append("html", fs.createReadStream(path.join(__dirname, "../assets/html/report.html")));
data.append('asset[]', fs.createReadStream(path.join(__dirname, `../assets/images/footerLogo.png`)))
data.append("style", fs.createReadStream(path.join(__dirname, "../assets/css/report.css")));

const configConvert = {
  url: "https://api.abc.com/pdf",  <== This will be weasyprint api url.
  headers: { ...data.getHeaders()},
  responseType: "arraybuffer",
  method: "post",
  timeout: 3000,
  data: data
};

const pdfResult = await axios(configConvert);
console.log(pdfResult.data)

First time, it works well but from second time i am getting this error. Weasyprint api is working well in postman.

cause: Error: socket hang up
      at connResetException (node:internal/errors:704:14)
      at TLSSocket.socketOnEnd (node:_http_client:505:23)
      at TLSSocket.emit (node:events:525:35)
      at TLSSocket.emit (node:domain:489:12)
      at endReadableNT (node:internal/streams/readable:1358:12)
      at processTicksAndRejections (node:internal/process/task_queues:83:21) {
    code: 'ECONNRESET'

Thanks in Advance.

I have tried setting timeout in axios and also added https agent keep alive but facing same error. Here is the code. I also referred to Axios documentation and StackOverflow questions.

const configConvert = {
 url: process.env.HTMLTOPDF_URL,
 headers: { ...data.getHeaders()},
 responseType: "arraybuffer",
 method: "post",
 timeout: 3000000,  <== setting timeout for 3000000 miliseconds.
 data: data
};
const https = require('https');
const httpsAgent = new https.Agent({ keepAlive: true });

const configConvert = {
 url: process.env.HTMLTOPDF_URL,
 headers: { ...data.getHeaders()},
 responseType: "arraybuffer",
 method: "post",
 httpsAgent,  <== setting https keepAlive agent. Also tried with httpAgent.
 data: data
};


Solution

  • Instead of using Axios, you can try calling the API using the core http or https library provided by nodejs.

    const https = require('https');
    const FormData = require('form-data');
    const fs = require('fs');
    
    const data = new FormData();
    data.append('html', fs.createReadStream(htmlPath));
    data.append('style', fs.createReadStream(cssPath));
    var req = https.request({
        'method': 'POST',
        'hostname': '<SOME_HOST>', // weasyprint host in your case
        'path': '<SOME_PATH>', // weasyprint path in your case
        'headers': {
            ...data.getHeaders()
        }
    });
    req.on('response', (res) => {
        if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
            res.pipe(fs.createWriteStream('generated.pdf'))
            console.log("PDF Saved")
        }
    });
    data.pipe(req);
    

    This way, the HTTP call won't throw a Socket Hang up error. You can convert the code to a return promise if needed.