@@ -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