Skip to content

Commit 31b08fb

Browse files
committed
improve error handling
1 parent 68dcdbb commit 31b08fb

1 file changed

Lines changed: 37 additions & 10 deletions

File tree

index.js

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ function wkhtmltopdf(input, options, callback) {
5757

5858
keys.forEach(function(key) {
5959
var val = options[key];
60-
if (key === 'ignore' || key === 'debug' || key === 'debugStdOut') { // skip adding the ignore/debug keys
60+
if (key === 'ignore' || key === 'debug' || key === 'debugStdOut' || key === 'timeout') { // skip adding the ignore/debug keys
6161
return false;
6262
}
6363

@@ -111,14 +111,24 @@ function wkhtmltopdf(input, options, callback) {
111111
var child = spawn(wkhtmltopdf.shell, ['-c', 'set -o pipefail ; ' + args.join(' ') + ' | cat'], spawnOptions);
112112
}
113113

114+
var timeout
115+
if (options.timeout) {
116+
timeout = setTimeout( function () {
117+
var timeoutError = new Error('Child process terminated due to timeout');
118+
timeoutError.code = '_EXIT_TIMEOUT';
119+
handleError(timeoutError);
120+
}, options.timeout*1000);
121+
}
122+
114123
var stream = child.stdout;
115124

116125
// call the callback with null error when the process exits successfully
117126
child.on('exit', function(code) {
118127
if (code !== 0) {
119-
stderrMessages.push('wkhtmltopdf exited with code ' + code);
128+
stderrMessages.code = code;
120129
handleError(stderrMessages);
121130
} else if (callback) {
131+
clearTimeout(timeout);
122132
callback(null, stream); // stream is child.stdout
123133
}
124134
});
@@ -127,12 +137,19 @@ function wkhtmltopdf(input, options, callback) {
127137
var stderrMessages = [];
128138
function handleError(err) {
129139
var errObj = null;
140+
var code;
141+
var parallelError;
130142
if (Array.isArray(err)) {
143+
code = err.code;
144+
parallelError = err.parallelError;
145+
// fix cutted lines in Windows
146+
err = Buffer.concat(err).toString();
147+
var lines = err.split(/[\r\n]+/).map( line => line.trim() ).filter( line => !!line )
131148
// check ignore warnings array before killing child
132149
if (options.ignore && options.ignore instanceof Array) {
133150
var ignoreError = false;
134151
options.ignore.forEach(function(opt) {
135-
err.forEach(function(error) {
152+
lines.forEach(function(error) {
136153
if (typeof opt === 'string' && opt === error) {
137154
ignoreError = true;
138155
}
@@ -145,10 +162,19 @@ function wkhtmltopdf(input, options, callback) {
145162
return true;
146163
}
147164
}
148-
errObj = new Error(err.join('\n'));
165+
errObj = new Error(lines[0] || ('Child process finished with exit code ' + code));
166+
errObj.code = '_EXIT_FAILURE';
167+
errObj.errno = code;
168+
errObj.details = err;
169+
errObj.parallelError = parallelError;
170+
} else if (err instanceof Error) {
171+
errObj = err;
149172
} else if (err) {
150-
errObj = new Error(err);
173+
errObj = new Error(err);
151174
}
175+
errObj.args = args;
176+
177+
clearTimeout(timeout);
152178
child.removeAllListeners('exit');
153179
child.kill();
154180
// call the callback if there is one
@@ -164,11 +190,11 @@ function wkhtmltopdf(input, options, callback) {
164190
}
165191

166192
child.once('error', function(err) {
167-
throw new Error(err); // critical error
193+
handleError(err); // critical error
168194
});
169195

170196
child.stderr.on('data', function(data) {
171-
stderrMessages.push((data || '').toString());
197+
stderrMessages.push(data);
172198
if (options.debug instanceof Function) {
173199
options.debug(data);
174200
} else if (options.debug) {
@@ -192,10 +218,11 @@ function wkhtmltopdf(input, options, callback) {
192218

193219
// write input to stdin if it isn't a url
194220
if (!isUrl) {
195-
// Handle errors on the input stream (happens when command cannot run)
196-
child.stdin.on('error', handleError);
197221
if (isStream(input)) {
198-
input.pipe(child.stdin);
222+
input.pipe(child.stdin)
223+
.on('error', function(e) {
224+
stderrMessages.parallelError = e;
225+
});
199226
} else {
200227
child.stdin.end(input);
201228
}

0 commit comments

Comments
 (0)