Skip to content

Commit b672aa8

Browse files
committed
Improve error handling and pipe stdout to process.stdout
1 parent f5fe191 commit b672aa8

File tree

1 file changed

+48
-37
lines changed

1 file changed

+48
-37
lines changed

lib/pdf.js

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -84,54 +84,65 @@ PDF.prototype.toFile = function PdfToFile (filename, callback) {
8484
}
8585

8686
PDF.prototype.exec = function PdfExec (callback) {
87-
var callbacked = false
8887
var child = childprocess.spawn(this.options.phantomPath, [].concat(this.options.phantomArgs, [this.script]))
89-
var stdout = []
9088
var stderr = []
89+
9190
var timeout = setTimeout(function execTimeout () {
92-
child.stdin.end()
93-
child.kill()
94-
if (!stderr.length) {
95-
stderr = [new Buffer('html-pdf: PDF generation timeout. Phantom.js script did not exit.')]
96-
}
91+
respond(null, new Error('html-pdf: PDF generation timeout. Phantom.js script did not exit.'))
9792
}, this.options.timeout)
9893

99-
child.stdout.on('data', function (buffer) {
100-
return stdout.push(buffer)
101-
})
102-
103-
child.stderr.on('data', function (buffer) {
94+
function onError (buffer) {
10495
stderr.push(buffer)
105-
child.stdin.end()
106-
return child.kill()
107-
})
96+
}
97+
98+
function onData (buffer) {
99+
var result
100+
try {
101+
var json = buffer.toString().trim()
102+
if (json) result = JSON.parse(json)
103+
} catch (err) {
104+
// Proxy for debugging purposes
105+
process.stdout.write(buffer)
106+
}
107+
108+
if (result) respond(null, null, result)
109+
}
108110

109-
function exit (err, data) {
111+
var callbacked = false
112+
function respond (code, err, data) {
110113
if (callbacked) return
111114
callbacked = true
112115
clearTimeout(timeout)
113-
if (err) return callback(err)
114-
return callback(null, data)
115-
}
116116

117-
child.on('error', exit)
118-
119-
child.on('exit', function (code) {
120-
if (code || stderr.length) {
121-
var err = new Error(Buffer.concat(stderr).toString() || 'html-pdf: Unknown Error')
122-
return exit(err)
123-
} else {
124-
try {
125-
var buff = Buffer.concat(stdout).toString()
126-
var data = (buff) != null ? buff.trim() : undefined
127-
data = JSON.parse(data)
128-
} catch (err) {
129-
return exit(err)
130-
}
131-
return exit(null, data)
117+
// If we don't have an exit code, we kill the process, ignore stderr after this point
118+
if (code === null) kill(child, onData, onError)
119+
120+
if (!data) {
121+
if (!err && code) err = new Error("html-pdf: Received the exit code '" + code + "'")
122+
else if (!err) err = new Error('html-pdf: Unknown Error')
123+
124+
var postfix = stderr.length ? '\n' + Buffer.concat(stderr).toString() : ''
125+
if (postfix) err.message += postfix
126+
return callback(err, null)
132127
}
133-
})
134128

135-
var res = JSON.stringify({html: this.html, options: this.options})
136-
return child.stdin.write(res + '\n', 'utf8')
129+
callback(null, data)
130+
}
131+
132+
child.stdout.on('data', onData)
133+
child.stderr.on('data', onError)
134+
child.on('error', function onError (err) { respond(null, err) })
135+
136+
// An exit event is most likely an error because we didn't get any data at this point
137+
child.on('exit', respond)
138+
139+
var config = JSON.stringify({html: this.html, options: this.options})
140+
return child.stdin.write(config + '\n', 'utf8')
141+
}
142+
143+
function kill (child, onData, onError) {
144+
child.stdout.removeListener('data', onData)
145+
child.stderr.removeListener('data', onError)
146+
child.stdin.end()
147+
child.kill()
137148
}

0 commit comments

Comments
 (0)