nginx + uwsgi + flask — отключение пользовательских страниц ошибок

Можно ли отключить пользовательские страницы ошибок nginx — если я могу их так назвать — для отображения страниц исключений моего фреймворка?

Я действительно не вижу, чтобы мой инструмент отладчика werkzeug отображался в html...

ОБНОВЛЕНИЕ

Хорошо, мне нужно сделать очень простое приложение для фляги, и я опубликую биты:

/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:

$ echo $PYTHONPATH
/home/my_user/dev/

Как я запускаю uwsgi:

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

Как я запускаю nginx:

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

Если я попаду на корневую страницу:

ошибка сервера

Если я запускаю nginx вручную, например:

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

Вместо этого я увижу и то, что хочу увидеть:

введите здесь описание изображения

Конечно, я убедился, что это сработает, когда я не вызывал исключение, а возвращал «Hello World», например, в моей функции index().

Это относится к пользовательским страницам ошибок в .NET. Я хочу отключить это и позволить nginx/uwsgi передавать html, сгенерированный отладчиком, непосредственно в браузер, а не внутреннюю ошибку сервера.

ОБНОВЛЕНИЕ 2

Теперь, если я изменю свое приложение фляги, чтобы включить режим отладки:

/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)

Затем я получаю ошибку 502.

Но если я вместо того, чтобы поднять 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)

Когда я открываю страницу (http://localhost:5000), в моем браузере отображается сообщение "Hello World".


person johnildergleidisson    schedule 21.06.2012    source источник
comment
Было бы лучше указать в вопросе, с какими страницами ошибок у вас проблемы, например. 502   -  person number5    schedule 22.06.2012
comment
Спасибо за ваше предложение, я добавил много новой информации, которая, надеюсь, поможет разобраться в проблеме.   -  person johnildergleidisson    schedule 04.07.2012


Ответы (3)


Эта страница «Внутренняя ошибка сервера» не от nginx, а от Flask. Это происходит, когда режим отладки выключен.

uwsgi импортирует ваш код как модуль, а не как скрипт. __name__ == '__main__' имеет значение False, и оператор if не выполняется. Попробуйте установить режим отладки за пределами if:

app = Flask(__name__)
app.debug = True

Однако настоятельно рекомендуется никогда не выходить из режима отладки на сервере в общедоступном Интернете, поскольку пользователь может заставить сервер выполнять любой код. Это серьезная проблема безопасности.

person Simon Sapin    schedule 27.07.2012
comment
Я думал, что это то, что: app.config.update(DEBUG=True) сделал - в настоящее время вне if... но я попробую, просто установив app.debug = True, как вы предлагаете, и сообщу вам результаты. - person johnildergleidisson; 30.07.2012
comment
app.debug = True должно совпадать с app.config.update(DEBUG=True) (1, 2) Убедитесь, что любой из них выполняется uwsgi. Проще всего поставить сразу после app = Flask(__name__) - person Simon Sapin; 30.07.2012
comment
Да, у меня в примере так. Я попробую еще раз, чтобы убедиться. Но на данный момент после включения режима отладки Flask я столкнулся с ошибкой 502 Bad Gateway, которую я бы указал на nginx... См. UPDATE2. - person johnildergleidisson; 30.07.2012

Используйте Flask#errorhandler, чтобы зарегистрировать собственные обработчики ошибок в flask. Например, чтобы заменить 404, вы должны сделать что-то вроде:

app = Flask()

@app.errorhandler(404)
def handel_404(error):
    return render_template('404.html')
person Trevor    schedule 21.06.2012
comment
Я имел в виду, что мне действительно нужно, чтобы при достижении raise Exception() в моем коде я видел отладчик werkzeug вместо страницы nginx 502 Bad Gateway. - person johnildergleidisson; 22.06.2012
comment
Ах, если вы получаете 502 Bad Gateway, значит, ошибка возникает до того, как ваше приложение сможет запуститься. Отладчик werkzeug может обрабатывать только ошибки, возникающие во время запроса. Вам нужно будет проверить журналы uwsgi на наличие трассировки стека, чтобы устранить проблему. - person Trevor; 22.06.2012
comment
Вы также можете изменить внешний вид страницы, добавив директиву error_page 502 =503 /error_page.html; в конфигурацию nginx, но это будет просто статическая страница. - person Trevor; 22.06.2012
comment
Как было предложено в моем ОБНОВЛЕНИИ 2, 502 Bad Gateway также будет происходить с необработанными исключениями в приложении. Nginx/uwsgi не пропускает. - person johnildergleidisson; 04.07.2012

Саймон Сапин действительно дал вам правильный ответ. Вам нужно включить отладку в Flask. Nginx не возвращает никаких пользовательских страниц ошибок, если вы явно не настроили его для этого.

Если вы используете следующий код, вы увидите свои отладочные сообщения из flask, проксированные через Nginx.

from flask import Flask

app = Flask(__name__)
app.debug = True

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

Согласно вашему обновлению 2. Вы видите 502 (плохой шлюз), потому что Flask просто не возвращает никакого ответа или ответ, который Nginx не понимает. 502 не является проблемой для Nginx. Это означает, что все, о чем Nginx пытается говорить (в данном случае ваше приложение flask), вообще не работает должным образом.

Однако во многих отношениях вам не следует этого делать. Режим отладки следует включать только тогда, когда вы запускаете flask на локальном компьютере разработчика. В любом случае, в этом весь смысл строки if __name__ == "__main__":.

person aychedee    schedule 19.09.2012