node-html-pdf icon indicating copy to clipboard operation
node-html-pdf copied to clipboard

Getting errors using this package in AWS Lambda Nodejs 10.x and up

Open Ragers opened this issue 4 years ago • 24 comments

I've been using this package for ages and worked like a charm on AWS Lambda with Nodejs 8.10 and older.

But AWS now forces you to use 10.x and later...

When I updated my version I started getting the following errors from the lambda execution stack:

ERROR	Uncaught Exception	
{
    "errorType": "Error",
    "errorMessage": "write EPIPE",
    "code": "EPIPE",
    "errno": "EPIPE",
    "syscall": "write",
    "stack": [
        "Error: write EPIPE",
        "    at WriteWrap.afterWrite [as oncomplete] (net.js:789:14)"
    ]
}

It also throws this error just before the above error:

Error: html-pdf: Received the exit code '127'
/var/task/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory

    at ChildProcess.respond (/var/task/node_modules/html-pdf/lib/pdf.js:121:31)
    at ChildProcess.emit (events.js:198:13)
    at ChildProcess.EventEmitter.emit (domain.js:448:20)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:248:12)

I have tried setting the phantomPath option, still did not help.

Any help will be greatly appreciated.

Ragers avatar Jan 10 '20 10:01 Ragers

I can confirm the same errors on Node10.x and Node12.x. It works on node 8.10 though.

Node 10.x

Error: spawn /phantom\\bin\\phantomjs.exe ENOENT
  at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19)
  at onErrorNT (internal/child_process.js:415:16)
  at process._tickCallback (internal/process/next_tick.js:63:19)
    
Error: spawn /phantom\bin\phantomjs.exe ENOENT
  at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19)
  at onErrorNT (internal/child_process.js:415:16)    at process._tickCallback (internal/process/next_tick.js:63:19)
errno: 'ENOENT',
code: 'ENOENT',
syscall: 'spawn /phantom\\bin\\phantomjs.exe',
path: '/phantom\\bin\\phantomjs.exe',
spawnargs: [ '/scripts/pdf_a4_portrait.js' ]

Node 12.x

Error: write EPIPE
  at afterWriteDispatched (internal/stream_base_commons.js:150:25)
  at writeGeneric (internal/stream_base_commons.js:141:3)
  at Socket._writeGeneric (net.js:770:11)
  at Socket._write (net.js:782:8)
  at doWrite (_stream_writable.js:431:12)
  at writeOrBuffer (_stream_writable.js:415:5)
  at Socket.Writable.write (_stream_writable.js:305:11)
  at PDF.PdfExec [as exec] (/var/task/src/post/webpack:/node_modules/html-pdf/lib/pdf.js:141:1)
  at PDF.PdfToBuffer [as toBuffer] (/var/task/src/post/webpack:/node_modules/html-pdf/lib/pdf.js:44:1)
  t /var/task/src/post/webpack:/src/lib/managers/EmailManager.ts:78:27

Error: spawn /phantom\bin\phantomjs.exe ENOENT
  at Process.ChildProcess._handle.onexit (internal/child_process.js:264:19)
  at onErrorNT (internal/child_process.js:456:16)
  at processTicksAndRejections (internal/process/task_queues.js:80:21) {
errno: 'ENOENT',
code: 'ENOENT',
syscall: 'spawn /phantom\\bin\\phantomjs.exe',
path: '/phantom\\bin\\phantomjs.exe',
spawnargs: [ '/scripts/pdf_a4_portrait.js' ]

alexwendte avatar Jan 10 '20 23:01 alexwendte

I facing this error in NodeJS 10.x and NodeJS 12.x but in the version 8.10 works fine.

The problem is tha AWS will discontinue the version 8.10 and they don't installed the lib

libfontconfig

alfnunes avatar Jan 11 '20 14:01 alfnunes

Two other resources got this fixed for me on Node 10:

For more context and a guide if you want to compile everything yourself: https://stackoverflow.com/questions/56795567/how-do-you-install-phantomjs-on-aws-lambda

Or get the output in this repo: https://github.com/naeemshaikh27/phantom-lambda-fontconfig-pack

As a minimum to get it working:

  • Copy all the .so files and put them in your project root
  • Copy the fonts.conf file and put in fonts directory
  • Add Lambda Environment Variable "FONTCONFIG_PATH" with value equal to fonts directory (so "/var/task/{FONTS_DIR}")

NOTE: LD_LIBRARY_PATH was not required for it to work

jeff-shep avatar Jan 27 '20 15:01 jeff-shep

I solved this issue following the steps of @jeff-shep but then my pdf was generated without any text so I had to change the content of fonts.config

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
  <dir>/var/task/fonts/</dir>
  <cachedir>/tmp/fonts-cache/</cachedir>
  <config></config>
</fontconfig>

https://forums.aws.amazon.com/thread.jspa?messageID=776307

taniasg avatar Jan 29 '20 20:01 taniasg

When using phantom-lambda-fontconfig-pack make sure to set FONTCONFIG_PATH to path.join(process.env['LAMBDA_TASK_ROOT'], '...'); instead of process.env['LAMBDA_TASK_ROOT'];, otherwise it'll render black boxes instead of letters.

catamphetamine avatar Jan 30 '20 14:01 catamphetamine

@jeff-shep @taniasg I am still facing errors even after following the steps mentioned above. I added the .so files, added environment variables and also created the fonts.conf but still facing same error for font lib files not found. Error: html-pdf: Received the exit code '127' /var/task/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directoryec2

Can you please confirm where the font libraries files should be copied. Currently, I have copied them at root folder, i.e. /var/task

anupkawtia avatar Feb 07 '20 17:02 anupkawtia

@anupkawtia I copied the fonts on my root project inside a directory named fonts including config file.

taniasg avatar Feb 07 '20 17:02 taniasg

@taniasg Thanks for responding. How about the font library files, libfontconfig.so.1 etc., where were they copied?

anupkawtia avatar Feb 07 '20 17:02 anupkawtia

@anupkawtia All the .so files are copied on my project root

taniasg avatar Feb 07 '20 17:02 taniasg

@taniasg I did the same but still facing the issue, not sure why it is not working. I have also added the environment variable. Any other pointers?

anupkawtia avatar Feb 07 '20 18:02 anupkawtia

@anupkawtia I pointed my FONTCONFIG_PATH to my fonts directory inside my project root Try this: process.env['FONTCONFIG_PATH'] = path.join(process.env['LAMBDA_TASK_ROOT'], 'fonts'); or process.env['FONTCONFIG_PATH'] = path.resolve(__dirname, "fonts");

taniasg avatar Feb 07 '20 18:02 taniasg

@taniasg Tried the same but that also did not help :( May be something wrong with the way my function is setup.. I will dig into it and get back. Thanks for your help.

anupkawtia avatar Feb 07 '20 20:02 anupkawtia

Just chiming in here: the method outlined by jeff-shep works for me, but I'm just wanting to know if anyone else is experiencing significant (30sec+) lambda timeouts on first, and subsequent runs using this method?

I'm using serverless framework to deploy the html-pdf lambda function to an API Gateway; and found that on deployment there's a huge lag period on the first request, resulting in frequent timeouts.. after about 5 or so minutes it comes right and generates the PDF I need in about 800ms. My logs say nothing, no errors etc.. it's really strange. None of my other functions are experiencing this.. 🤔

Directory:

+ fonts
   + fonts.config
   + *.ttf
+ src
+ lib*.so.[version]
+ node_modules
+ package.json
+ serverless.yml

z0nekill avatar Feb 08 '20 11:02 z0nekill

it worked! thanks @jeff-shep and @taniasg

dfloresgonz avatar Feb 11 '20 00:02 dfloresgonz

@z0nekill - are you upgrading an existing function or deploying a new one? Just wondering if the issue was in the transition to Node v10 from a running Node 6/8 runtime on AWS side during your deployment.

jeff-shep avatar Feb 11 '20 09:02 jeff-shep

I have followed @jeff-shep steps and was able to fix libfontconfig.so.1 error. But after this fix i am getting below error:

libbz2.so.1: cannot open shared object file: No such file or directory.

Any help will be greatly appreciated.

Abhishek304 avatar Aug 06 '20 05:08 Abhishek304

@Abhishek304 - at this point I would recommend ditching node-html-pdf for an alternative library that doesn't rely on phantomJS, otherwise you'll be chasing down missing libs for days. I'll be considering using https://github.com/zeplin/zeplin-html-to-pdf when I lifecycle our PDF microservices.

jeff-shep avatar Aug 06 '20 08:08 jeff-shep

Thanks @jeff-shep for quick response.

We are using Phantom to convert SVG in PNG image. And i think think node-html-pdf will not work for me. Please suggest any other workaround. Or how can i download this libbz2.so.1 for linux 2.

Abhishek304 avatar Aug 06 '20 09:08 Abhishek304

@jeff-shep - finally i am able to resolve phantomJS dependencies issue by following your steps. And to libbiz2.so.1 issue i have executed below command through dockerfile:

run command yum install bzip2 bzip2-devel

It may help someone.

Thanks @jeff-shep

Abhishek304 avatar Aug 10 '20 12:08 Abhishek304

Anyone achieved this on Vercel by any chance?

matiastucci avatar Aug 14 '20 10:08 matiastucci

I am also facing the same issue on Microsoft azure app server "error": { "status": 500, "message": "html-pdf: Received the exit code '127'\n/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory\n" }

anilpandey199905 avatar Sep 26 '20 14:09 anilpandey199905

The pdf generator packages are deprecated and don't work on aws lambdas, just this new package I found.

https://www.npmjs.com/package/html-pdf-lambda

xxdannilinxx avatar Sep 15 '21 11:09 xxdannilinxx

Just wanted to add my success story here. @ jeff-shep 's method works for me. I'm using severless-webpack with a custom webpack config, so I needed to remember to copy (using copyPlugin) all of the .so files to the root dir after webpacking.

Thanks all very much for these details. Really helped me out a lot.

paulegradie avatar Oct 04 '21 14:10 paulegradie

hey @paulegradie I also did the same thing but , can you paste code for last point about copyPlugin, I did in this way,

plugins: [ new webpack.EnvironmentPlugin({ NODE_ENV: "development" }), new CopyPlugin({ patterns: [ { from: "**.so.**", to: ".serverless/**.zip" }, ], }), ]

but error is still there for me,

Error: html-pdf: Unknown Error /var/task/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs: /var/task/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs: cannot execute binary file

P.S. I'm using severless-webpack with a custom webpack config

cc: @jeff-shep @taniasg

iamsurajdc avatar Oct 12 '22 17:10 iamsurajdc