I have a uWSGI application written in Python using the Pyramid framework.
Nginx is configured like below (I left out a few bits, but I don't think they will matter):
upstream uwsgicluster {
server 127.0.0.1:8989;
}
# Proxying connections to application servers
location / {
include uwsgi_params;
uwsgi_pass uwsgicluster;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
uWSGI is configured like this (using a .ini file):
[uwsgi]
socket = 127.0.0.1:8989
master = true
home = /home/user/userenv
paste = config:/home/user/userenv/app/production.ini
harakiri = 30
logto = /home/user/userenv/log/app.log
Everything works great. uWSGI is managed with Supervisor.
What I want to do is get my HTTP 500 responses to Nginx, and to the browser in some cases.
Currently, when there is a HTTP 500 the stack trace goes to the log file correctly, but zero bytes are returned to Nginx.
[pid: 19826|app: 0|req: 117/117] 192.168.10.54 () {38 vars in 469 bytes} [Tue Nov 11 02:46:53 2014] POST /jsonendpoint => generated 0 bytes in 2 msecs (HTTP/1.1 500) 0 headers in 0 bytes (0 switches on core 0)
Prior to this is a Python stack trace and an typical Python exception that was not handled. Everything works as expected.
The question: How can I get uWSGI to return the contents of the 500 response to Nginx (and thus the browser). Right now its generating 0 bytes. Is this something that I need to configure deeper in my Python framework?
For reference, I am using a completely standard (zero changes other than database connection string) Pyramid config: https://github.com/Pylons/pyramid/blob/master/pyramid/scaffolds/alchemy/production.ini_tmpl
EDIT BELOW
I figured this one out.
The answer is that my Pyramid application was not returning any data.
If you define a view, as below, with a context of Exception, this view runs for all exceptions. I am still working out how to get the whole stack trace (since this isn't in a Python exception handler, but anyhow, the main question was answered).
@view_config(context=Exception)
def failed_validation(exc, request):
msg = exc.args[0] if exc.args else ""
response = Response('Exception: %s' % msg)
So, a sub question is: How to get the entire stack trace. This will probably be a combined Pyramid/Python answer.