Skip to content

Commit 48033ec

Browse files
authored
Merge pull request JazzCore#107 from SelfHacked/master
Look for 'Done' in stderr when exit code is non-zero
2 parents eb3ccc4 + 440596e commit 48033ec

File tree

1 file changed

+49
-34
lines changed

1 file changed

+49
-34
lines changed

pdfkit/pdfkit.py

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,39 @@ def _command(self, path=None):
125125
def command(self, path=None):
126126
return list(self._command(path))
127127

128+
@staticmethod
129+
def handle_error(exit_code, stderr):
130+
if exit_code == 0:
131+
return
132+
133+
# Sometimes wkhtmltopdf will exit with non-zero
134+
# even if it finishes generation.
135+
# If will display 'Done' in the second last line
136+
if stderr.splitlines()[-2].strip() == 'Done':
137+
return
138+
139+
if 'cannot connect to X server' in stderr:
140+
raise IOError('%s\n'
141+
'You will need to run wkhtmltopdf within a "virtual" X server.\n'
142+
'Go to the link below for more information\n'
143+
'https://github.com/JazzCore/python-pdfkit/wiki/Using-wkhtmltopdf-without-X-server' % stderr)
144+
145+
if 'Error' in stderr:
146+
raise IOError('wkhtmltopdf reported an error:\n' + stderr)
147+
148+
error_msg = stderr or 'Unknown Error'
149+
raise IOError("wkhtmltopdf exited with non-zero code {0}. error:\n{1}".format(exit_code, error_msg))
150+
128151
def to_pdf(self, path=None):
129152
args = self.command(path)
130-
131-
result = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
132-
stderr=subprocess.PIPE, env=self.environ)
153+
154+
result = subprocess.Popen(
155+
args,
156+
stdin=subprocess.PIPE,
157+
stdout=subprocess.PIPE,
158+
stderr=subprocess.PIPE,
159+
env=self.environ
160+
)
133161

134162
# If the source is a string then we will pipe it into wkhtmltopdf.
135163
# If we want to add custom CSS to file then we read input file to
@@ -141,46 +169,34 @@ def to_pdf(self, path=None):
141169
input = self.source.source.read().encode('utf-8')
142170
else:
143171
input = None
172+
144173
stdout, stderr = result.communicate(input=input)
145174
stderr = stderr or stdout
146-
175+
stderr = stderr.decode('utf-8', errors='replace')
147176
exit_code = result.returncode
148-
if exit_code != 0:
149-
stderr = stderr.decode('utf-8', errors='replace')
150-
151-
if 'cannot connect to X server' in stderr:
152-
raise IOError('%s\n'
153-
'You will need to run wkhtmltopdf within a "virtual" X server.\n'
154-
'Go to the link below for more information\n'
155-
'https://github.com/JazzCore/python-pdfkit/wiki/Using-wkhtmltopdf-without-X-server' % stderr)
156-
157-
if 'Error' in stderr:
158-
raise IOError('wkhtmltopdf reported an error:\n' + stderr)
159-
160-
error_msg = stderr or 'Unknown Error'
161-
raise IOError("wkhtmltopdf exited with non-zero code {0}. error:\n{1}".format(exit_code, error_msg))
177+
self.handle_error(exit_code, stderr)
162178

163179
# Since wkhtmltopdf sends its output to stderr we will capture it
164180
# and properly send to stdout
165181
if '--quiet' not in args:
166-
sys.stdout.write(stderr.decode('utf-8', errors='replace'))
182+
sys.stdout.write(stderr)
167183

168184
if not path:
169185
return stdout
170-
else:
171-
try:
172-
with codecs.open(path, encoding='utf-8') as f:
173-
# read 4 bytes to get PDF signature '%PDF'
174-
text = f.read(4)
175-
if text == '':
176-
raise IOError('Command failed: %s\n'
177-
'Check whhtmltopdf output without \'quiet\' '
178-
'option' % ' '.join(args))
179-
return True
180-
except (IOError, OSError) as e:
181-
raise IOError('Command failed: %s\n'
182-
'Check whhtmltopdf output without \'quiet\' option\n'
183-
'%s ' % (' '.join(args), e))
186+
187+
try:
188+
with codecs.open(path, encoding='utf-8') as f:
189+
# read 4 bytes to get PDF signature '%PDF'
190+
text = f.read(4)
191+
if text == '':
192+
raise IOError('Command failed: %s\n'
193+
'Check whhtmltopdf output without \'quiet\' '
194+
'option' % ' '.join(args))
195+
return True
196+
except (IOError, OSError) as e:
197+
raise IOError('Command failed: %s\n'
198+
'Check whhtmltopdf output without \'quiet\' option\n'
199+
'%s ' % (' '.join(args), e))
184200

185201
def _normalize_options(self, options):
186202
""" Generator of 2-tuples (option-key, option-value).
@@ -206,7 +222,6 @@ def _normalize_options(self, options):
206222
else:
207223
yield (normalized_key, unicode(value) if value else value)
208224

209-
210225
def _normalize_arg(self, arg):
211226
return arg.lower()
212227

0 commit comments

Comments
 (0)