Pregunta

I'm using Apache 2.2.22 on Precise with mod_wsgi 3.3-4 to run a python 2.7 WSGI application (Openstack Ceilometer) running Python Pecan 0.2.1.

When the WSGI application throws an exception (a wsme.exc.ClientSideError) with status_code set to 401 (or anything else), Apache reports the error in the application's log as a 500 and the client receives a 500 status code.

It reports an Internal Server Error no matter what type of exception was thrown.

I would like the error code and message returned to the client to reflect what was thrown by the WSGI application, not be 500 every time.

I tried using Paste's [ErrorMiddleware][3] class to wrap the WSGI application and I understood from this that it would produce the results I wanted. No luck.

Here is how I wrap the application with ErrorMiddleware:

from ceilometer import service
from ceilometer.api import app 
import sys 
from paste.exceptions.errormiddleware import ErrorMiddleware
sys.stdout = sys.stderr

# Initialize the oslo configuration library and logging
service.prepare_service([])

wsgi_app = app.VersionSelectorApplication()
application = ErrorMiddleware(application=wsgi_app, show_exceptions_in_wsgi_errors=True, debug=True)

The only clue I see in Apache's error log is this:

[Tue Apr 08 22:45:18 2014] [error] [client 127.0.0.1] mod_wsgi (pid=21955): Exception occurred processing WSGI script '/usr/share/pyshared/ceilometer/api/app.wsgi'.
[Tue Apr 08 22:45:18 2014] [error] [client 127.0.0.1] TypeError: expected byte string object for header value, value of type int found

My application WSGI config file (/etc/apache2/sites-enabled/ceilometer) contains this:

<VirtualHost *:8777>

WSGIScriptAlias / /usr/share/pyshared/ceilometer/api/app.wsgi

# Number of process and threads should be configurable
WSGIDaemonProcess ceilometer user=meterAccount group=meter processes=3 threads=64
WSGIProcessGroup ceilometer

ErrorLog /var/log/ceilometer-apache/ceilometer_error.log
LogLevel warn
CustomLog /var/log/ceilometer-apache/ceilometer_access.log combined
SSLEngine on
SSLVerifyClient optional
SSLOptions +stdEnvVars
SSLVerifyDepth 3
SSLCertificateFile /etc/apache2/ssl/ceilometer.cer
SSLCertificateKeyFile /etc/apache2/ssl/ceilometer.key
SSLCACertificateFile /etc/ssl/certs/ca-certificates.crt

</VirtualHost>

Am I missing something in my use of ErrorMiddleware, or is there a better tool to use to propagate error info from the WSGI app through Apache to the response sent to the client?

I'm not using Django and have read the other 500 error questions related to mod_wsgi but there's only one dealing with ErrorMiddlware and it wasn't helpful.

Sending error info by email isn't an option in this case.

Edit: Cause is as described in accepted answer. Ceilometer dev team found a bug and fixed it:

https://bugs.launchpad.net/ceilometer/+bug/1306963 https://review.openstack.org/#/c/87084/

Verified the patch works.

¿Fue útil?

Solución

In respect of the error:

[Tue Apr 08 22:45:18 2014] [error] [client 127.0.0.1] mod_wsgi (pid=21955): Exception occurred processing WSGI script '/usr/share/pyshared/ceilometer/api/app.wsgi'.
[Tue Apr 08 22:45:18 2014] [error] [client 127.0.0.1] TypeError: expected byte string object for header value, value of type int found

the values for all response headers are meant to be strings. You are setting one as an integer and so it fails. This is because mod_wsgi is strict as far as application of the WSGI specification.

Some pure Python WSGI servers in particular aren't strict and violate the WSGI specification by automatically converting the value to a string.

So possibly some part of your code of third party code you are using is not compliant with the WSGI specification.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top