@@ -84,54 +84,65 @@ PDF.prototype.toFile = function PdfToFile (filename, callback) {
84
84
}
85
85
86
86
PDF . prototype . exec = function PdfExec ( callback ) {
87
- var callbacked = false
88
87
var child = childprocess . spawn ( this . options . phantomPath , [ ] . concat ( this . options . phantomArgs , [ this . script ] ) )
89
- var stdout = [ ]
90
88
var stderr = [ ]
89
+
91
90
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.' ) )
97
92
} , this . options . timeout )
98
93
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 ) {
104
95
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
+ }
108
110
109
- function exit ( err , data ) {
111
+ var callbacked = false
112
+ function respond ( code , err , data ) {
110
113
if ( callbacked ) return
111
114
callbacked = true
112
115
clearTimeout ( timeout )
113
- if ( err ) return callback ( err )
114
- return callback ( null , data )
115
- }
116
116
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 )
132
127
}
133
- } )
134
128
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 ( )
137
148
}
0 commit comments