diff --git a/docs/content/reference/settings.md b/docs/content/reference/settings.md index 76b58d5b..ea9333af 100644 --- a/docs/content/reference/settings.md +++ b/docs/content/reference/settings.md @@ -73,6 +73,11 @@ because it consumes less system resources. In order to use the inotify reloader, you must have the ``inotify`` package installed. +!!! warning + Enabling this will change what happens on failure to load the + the application: While the reloader is active, any and all clients + that can make requests can see the full exception and traceback! + ### `reload_engine` **Command line:** `--reload-engine STRING` diff --git a/gunicorn/config.py b/gunicorn/config.py index ffbc1b27..1e0565f2 100644 --- a/gunicorn/config.py +++ b/gunicorn/config.py @@ -952,6 +952,10 @@ class Reload(Setting): .. note:: In order to use the inotify reloader, you must have the ``inotify`` package installed. + .. warning:: + Enabling this will change what happens on failure to load the + the application: While the reloader is active, any and all clients + that can make requests can see the full exception and traceback! ''' diff --git a/gunicorn/workers/base.py b/gunicorn/workers/base.py index c7a46e0e..ca6cf10b 100644 --- a/gunicorn/workers/base.py +++ b/gunicorn/workers/base.py @@ -128,6 +128,7 @@ class Worker: time.sleep(0.1) sys.exit(0) + self.log.warning("Reloader is on. Use in development only!") reloader_cls = reloader_engines[self.cfg.reload_engine] self.reloader = reloader_cls(extra_files=self.cfg.reload_extra_files, callback=changed) @@ -151,19 +152,12 @@ class Worker: self.log.exception(e) - # fix from PR #1228 - # storing the traceback into exc_tb will create a circular reference. - # per https://docs.python.org/2/library/sys.html#sys.exc_info warning, - # delete the traceback after use. - try: - _, exc_val, exc_tb = sys.exc_info() - self.reloader.add_extra_file(exc_val.filename) + if self.reloader is not None and e.filename is not None: + self.reloader.add_extra_file(e.filename) - tb_string = io.StringIO() - traceback.print_tb(exc_tb, file=tb_string) + with io.StringIO() as tb_string: + traceback.print_exception(e, file=tb_string) self.wsgi = util.make_fail_app(tb_string.getvalue()) - finally: - del exc_tb def init_signals(self): # reset signaling