node-html-pdf
node-html-pdf copied to clipboard
Getting errors using this package in AWS Lambda Nodejs 10.x and up
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.
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' ]
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
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
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
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.
@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 I copied the fonts on my root project inside a directory named fonts including config file.
@taniasg Thanks for responding. How about the font library files, libfontconfig.so.1 etc., where were they copied?
@anupkawtia All the .so files are copied on my project root
@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 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 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.
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
it worked! thanks @jeff-shep and @taniasg
@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.
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 - 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.
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.
@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
Anyone achieved this on Vercel by any chance?
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" }
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
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.
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