Skip to content

Commit c9f6a0f

Browse files
committed
child process exit event fires before IO is complete, causing errors
Under heavy load (in the context of web application, for example using nestjs) some of the requests fail: 1. According to child process documentation (https://nodejs.org/docs/latest-v14.x/api/child_process.html#child_process_event_exit), exit even can fire before stdio is closed. In such cases respond() is being called with code 0 (success), no error and no data. This results in an error in the calling code, because filename is expected but is not returned. I added additional error checking to respond() to handle this case. 2. Given the above, it's probably not a good idea to subscribe to exit event at all. I commented out the on('exit'..) code. on('close') should be sufficient. Tested it under some load (30 concurrent connections for 2 minutes) - no errors, 5000+ PDFs rendered.
1 parent 7e8c02a commit c9f6a0f

File tree

2 files changed

+6
-3
lines changed

2 files changed

+6
-3
lines changed

lib/pdf.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,15 @@ PDF.prototype.exec = function PdfExec (callback) {
123123
// Ignore if code has a value of 0 since that means PhantomJS has executed and exited successfully.
124124
// Also, as per your script and standards, having a code value of 1 means one can always assume that
125125
// an error occured.
126-
if (((typeof code !== 'undefined' && code !== null) && code !== 0) || err) {
126+
if (((typeof code !== 'undefined' && code !== null) && code !== 0) || err || (code === 0 && !data)) {
127127
var error = null
128128

129129
if (err) {
130130
// Rudimentary checking if err is an instance of the Error class
131131
error = err instanceof Error ? err : new Error(err)
132+
} else if (code === 0 && !data) {
133+
// This is to catch the edge case of having a exit code value of 0 but having no data (exit can be called before io pipes are closed)
134+
error = new Error('html-pdf: Process exited successfully, but no data received')
132135
} else {
133136
// This is to catch the edge case of having a exit code value of 1 but having no error
134137
error = new Error('html-pdf: Unknown Error')
@@ -150,7 +153,7 @@ PDF.prototype.exec = function PdfExec (callback) {
150153

151154
// An exit event is most likely an error because we didn't get any data at this point
152155
child.on('close', respond)
153-
child.on('exit', respond)
156+
// child.on('exit', respond)
154157

155158
var config = JSON.stringify({html: this.html, options: this.options})
156159
child.stdin.write(config + '\n', 'utf8')

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "html-pdf",
3-
"version": "3.0.1",
3+
"version": "3.0.2-kv",
44
"description": "HTML to PDF converter that uses phantomjs",
55
"engines": {
66
"node": ">=4.0.0"

0 commit comments

Comments
 (0)