Publish full exception when the application fails to load (#3462)

* Python3: refactor returned traceback

Exceptions provide __traceback__ reference since Python 3.0
(and creating cyclic references has not been big deal since Python 2.2)

* --reload: publish entire exception, not just traceback

This is dangerous insofar as the exception text is more
likely to contain secrets than the quoted lines from traceback are.

However, the difference between the two is minor compared to the
primary danger of enabling this on a production machine, so focus
on that instead!
This commit is contained in:
Paul J. Dorn 2026-01-25 09:41:39 +01:00 committed by GitHub
parent 98156f9ef6
commit 481dbf2e9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 14 additions and 11 deletions

View File

@ -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`

View File

@ -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!
'''

View File

@ -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