Почему Paste ErrorMiddleware выдает исключение, когда я использую его с моим приложением Python 3 mod_wsgi?

Я пытаюсь использовать ErrorMiddleware, включенный в Python Paste 2.0.3, чтобы показать трассировку в браузере, когда мой сервер приложений Python 3.4 mod_wsgi выдает исключение. Проблема, с которой я сталкиваюсь, заключается в том, что ErrorMiddleware выдает это исключение всякий раз, когда пытается обработать исключения моего сервера:

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

и поэтому я все еще получаю 500 Internal Server Error в браузере.

Похоже, проблема в том, что ErrorMiddleware пытается записать байты в поток ошибок wsgi:

    if six.PY3:
        line = line.encode('utf8')
    error_stream.write(line) # line 391 error_stream comes from environ['wsgi.errors']

но если я распечатаю environ['wsgi.errors'], это будет текстовый поток:

'wsgi.errors': <_io.TextIOWrapper name='<wsgi.errors>' encoding='utf-8'>

что означает, что ErrorMiddleware не может записывать в него байты.

Я оборачиваю свое приложение в ErrorMiddleware следующим образом:

application = ErrorMiddleware(application, debug=True)

Есть ли что-то, что я делаю неправильно, чтобы вызвать это? Могу ли я настроить mod_wsgi так, чтобы поток ошибок был потоком байтов, а не текстовым потоком?


person gla3dr    schedule 28.06.2017    source источник


Ответы (1)


Теоретически wsgi.errors должен вести себя так же, как запись в 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

Так что выглядит неправильно, что они попытаются записать байты на Python 3.

person Graham Dumpleton    schedule 28.06.2017
comment
Я примерно так и думал. Спасибо за подтверждение. - person gla3dr; 29.06.2017