11

Is it possible to disable nginx's custom error pages - if I may call them that - to display my framework's exception pages?

I can't really see my werkzeug debugger tool rendered in html...

UPDATE

OK, I got to make a very very simple flask application to work and I'll post the bits:

/home/my_user/.virtualenvs/nginx-test/etc/nginx.conf

worker_processes 1;
events { worker_connections 1024; }
http {
        server {
                listen 5000;
                server_name localhost;
                access_log /home/my_user/.virtualenvs/nginx-test/lib/nginx/access.log;
                error_log /home/my_user/.virtualenvs/nginx-test/lib/nginx/error.log;

                location / {
                        include uwsgi_params;
                        uwsgi_pass unix:/tmp/uwsgi.sock;
                }
        }
}

/home/my_user/dev/nginx_test/___init___.py

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    raise Exception()

if __name__ == '__main__':
    app.run('0.0.0.0', debug=True)

PYTHONPATH environment variable:

$ echo $PYTHONPATH
/home/my_user/dev/

How I run uwsgi:

$ uwsgi -s /tmp/uwsgi.sock --module nginx_test --callable app

How I run nginx:

$ nginx -c ~/.virtualenvs/nginx-test/etc/nginx.conf -p ~/.virtualenvs/nginx-test/lib/nginx/

If I hit the root page:

server error

If I run nginx manually like:

python /home/my_user/dev/nginx_test/___init___.py

I will see instead, and what I want to see:

enter image description here

Of course I made sure it would work when I didn't raise the exception, but returned 'Hello World' for example on my index() function.

This is referred to custom error pages in .NET. I want to disable this and let nginx/uwsgi pass the html generated by the debugger directly to the browser instead of the internal server error thing.

UPDATE 2

Now if I change my flask app to enable debugging mode by:

/home/my_user/dev/nginx_test/___init___.py

from flask import Flask

app = Flask(__name__)
app.config.update(DEBUG=True)
@app.route('/')
def index():
    raise Exception()

if __name__ == '__main__':
    app.run('0.0.0.0', debug=True)

Then I get 502 error.

But if I instead of raise Exception:

/home/my_user/dev/nginx_test/___init___.py

from flask import Flask

app = Flask(__name__)
app.config.update(DEBUG=True)
@app.route('/')
def index():
    return 'Hello World'

if __name__ == '__main__':
    app.run('0.0.0.0', debug=True)

I get 'Hello World' on my browser when I hit the page (http://localhost:5000).

johnildergleidisson
  • 2,087
  • 3
  • 30
  • 50
  • 1
    Would be better to state in the question that which error pages you have problem with eg. 502 – number5 Jun 22 '12 at 00:29
  • Thanks for your suggestion, I've added a whole lot of new information that would hopefully help figuring the issue out. – johnildergleidisson Jul 04 '12 at 19:15
  • Also see here: https://stackoverflow.com/questions/10364854/flask-debug-true-does-not-work-when-going-through-uwsgi – Rufat Dec 01 '21 at 09:57

3 Answers3

8

This "Internal Server Error" page is not from nginx but from Flask. It does so when debug mode is off.

uwsgi is importing your code as a module, not running at as a script. __name__ == '__main__' is False and the if statement is not executed. Try setting debug mode outside of the if:

app = Flask(__name__)
app.debug = True

However, it is strongly recommended to never leave the debug mode on a server on the public internet, since the user can make the server run any code. This is a serious security issue.

Simon Sapin
  • 9,790
  • 3
  • 35
  • 44
  • I thought that was what: app.config.update(DEBUG=True) did - currently out of the if... but I'll try it just by setting app.debug = True as you suggest and let you know the results. – johnildergleidisson Jul 30 '12 at 13:00
  • app.debug = True should be the same as app.config.update(DEBUG=True) ([1](https://github.com/mitsuhiko/flask/blob/0.9/flask/app.py#L170), [2](https://github.com/mitsuhiko/flask/blob/0.9/flask/config.py#L21)) Make sure that either of these is executed by uwsgi. The easiest is to put in right after `app = Flask(__name__)` – Simon Sapin Jul 30 '12 at 14:12
  • Yeah, that's how I do in my example. I'll try again just to make sure. But for now after enabling Flask's debugging mode, I'm hit with the 502 Bad Gateway error, which I'd pinpoint to nginx... See UPDATE2. – johnildergleidisson Jul 30 '12 at 17:14
1

Use Flask#errorhandler to register your own error handlers in flask. For example to replace the 404 you would do something like:

app = Flask()

@app.errorhandler(404)
def handel_404(error):
    return render_template('404.html')
Trevor
  • 9,518
  • 2
  • 25
  • 26
  • I meant, what I really need is to when `raise Exception()` is reached in my code, I see the werkzeug debugger instead of nginx 502 Bad Gateway page – johnildergleidisson Jun 21 '12 at 20:37
  • 2
    Ah, If you're getting a 502 Bad Gateway, then the error is happing before your app get's a chance to start. The werkzeug debugger can only handle errors that happen durring a request. You'll have to check your uwsgi logs for a stack trace to fix the problem. – Trevor Jun 21 '12 at 21:01
  • 1
    You can also change what the page looks like by adding a `error_page 502 =503 /error_page.html;` directive in your nginx config but that will just be a static page. – Trevor Jun 21 '12 at 21:02
  • As suggested by my UPDATE 2, the 502 Bad Gateway will also happen with on-application uncaught exceptions. Nginx/uwsgi isn't letting it through. – johnildergleidisson Jul 04 '12 at 19:17
1

Simon Sapin has really given you the correct answer. You need to enable debug in Flask. Nginx does not return any custom error pages unless you explictly configure it to do so.

If you use the following code you will see your debug messages from flask, proxied via Nginx.

from flask import Flask

app = Flask(__name__)
app.debug = True

@app.route('/')
def index():
    raise Exception()

As per your update 2. You are seeing a 502 (bad gateway) because Flask is simply not returning any response at all, or a response that Nginx does not understand. A 502 is not a problem with Nginx. It means that whatever Nginx is trying to talk (your flask app in this case) is not working properly at all.

However, in many ways you shouldn't be doing this. Debugging mode should only be enabled when you are running flask on your local dev machine. Which is the whole point of the if __name__ == "__main__": line anyway.

aychedee
  • 24,871
  • 8
  • 79
  • 83