I am trying to use the ErrorMiddleware included in Python Paste 2.0.3 in order to show tracebacks in the browser when my Python 3.4 mod_wsgi application server throws an exception. The issue I am having is that the ErrorMiddleware is throwing this exception whenever it attempts to handle my server's exceptions:
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.4/site-packages/paste/exceptions/errormiddleware.py", line 154, in __call__
response = self.exception_handler(exc_info, environ)
File "/usr/lib/python3.4/site-packages/paste/exceptions/errormiddleware.py", line 188, in exception_handler
simple_html_error=simple_html_error)
File "/usr/lib/python3.4/site-packages/paste/exceptions/errormiddleware.py", line 391, in handle_exception
error_stream.write(line)
TypeError: must be str, not bytes
and so I am still just getting 500 Internal Server Error
in the browser.
The issue seems to be that the ErrorMiddleware is trying to write bytes to the wsgi error stream:
if six.PY3:
line = line.encode('utf8')
error_stream.write(line) # line 391 error_stream comes from environ['wsgi.errors']
but if I print out environ['wsgi.errors']
it appears to be a text stream:
'wsgi.errors': <_io.TextIOWrapper name='<wsgi.errors>' encoding='utf-8'>
which means the ErrorMiddleware can't write bytes to it.
I am wrapping my application in the ErrorMiddleware like this:
application = ErrorMiddleware(application, debug=True)
Is there something I am doing wrong to cause this? Can I configure mod_wsgi so that the error stream is a byte stream instead of a text stream?
The wsgi.errors
should notionally behave the same as writing to sys.stdout
.
$ python3.6
Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.stdout.write('hello\n')
hello
6
>>> sys.stdout.write(b'hello\n')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: write() argument must be str, not bytes
So it looks wrong that they would attempt to write bytes on Python 3.