From 5c48cee0ec3922fc8d83cd217d480d9486fcab2d Mon Sep 17 00:00:00 2001 From: Braedon Vickers Date: Thu, 27 Sep 2018 15:09:23 +1200 Subject: Provide exc_info to start_response() when handling exceptions Recommended by pep-3333 to enable middleware to provide exception handling services, e.g. custom exception logging. See https://www.python.org/dev/peps/pep-3333/#error-handling Note that the exc_info is temporarily stored in the environ to pass it up from _handler() to wsgi(), where start_response() is called. There may be a better way to do this, e.g. storing it in the response object. --- bottle.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/bottle.py b/bottle.py index 45e85d1..68f2253 100755 --- a/bottle.py +++ b/bottle.py @@ -1025,6 +1025,7 @@ class Bottle(object): stacktrace = format_exc() environ['wsgi.errors'].write(stacktrace) environ['wsgi.errors'].flush() + environ['bottle.exc_info'] = sys.exc_info() out = HTTPError(500, "Internal Server Error", E, stacktrace) out.apply(response) @@ -1105,6 +1106,7 @@ class Bottle(object): def wsgi(self, environ, start_response): """ The bottle WSGI-interface. """ + provided_exc_info = False try: out = self._cast(self._handle(environ)) # rfc2616 section 4.3 @@ -1112,11 +1114,16 @@ class Bottle(object): or environ['REQUEST_METHOD'] == 'HEAD': if hasattr(out, 'close'): out.close() out = [] - start_response(response._wsgi_status_line(), response.headerlist) + exc_info = environ.get('bottle.exc_info') + if exc_info is not None: + del environ['bottle.exc_info'] + provided_exc_info = True + start_response(response._wsgi_status_line(), response.headerlist, exc_info) return out except (KeyboardInterrupt, SystemExit, MemoryError): raise except Exception as E: + if provided_exc_info: raise if not self.catchall: raise err = '

Critical error while processing request: %s

' \ % html_escape(environ.get('PATH_INFO', '/')) -- cgit v1.2.1