From 0ff82e1c05486b4b2f705722cd1ee98f431b76ab Mon Sep 17 00:00:00 2001
From: Edward Betts <edward@4angle.com>
Date: Fri, 29 Sep 2023 18:03:39 +0100
Subject: [PATCH] Update error handling to work with werkzeug 2

Closes: #1
---
 templates/show_error.html | 19 ++++++-------------
 web_view.py               | 25 +++++++++++++++++++------
 2 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/templates/show_error.html b/templates/show_error.html
index e75e75e..dd79c3c 100644
--- a/templates/show_error.html
+++ b/templates/show_error.html
@@ -7,24 +7,17 @@
 {% block content %}
 <div class="p-2">
 
-<h1>Software error: {{ tb.exception_type }}</h1>
+<h1>Software error: {{ exception_type }}</h1>
 <div>
-  <pre>{{ tb.exception }}</pre>
+  <pre>{{ exception }}</pre>
 </div>
 
-{% set body %}
-URL: {{ request.url }}
-
-{{ tb.plaintext | safe }}
-{% endset %}
-
-<p><a class="btn btn-primary btn-lg" role="button" href="https://github.com/EdwardBetts/dab-mechanic/issues/new?title={{ tb.exception + " " + request.url | urlencode }}&body={{ body | urlencode }}">Submit as an issue on GitHub</a> (requires an account with GitHub)</p>
-
 <h2 class="traceback">Traceback <em>(most recent call last)</em></h2>
-{{ tb.render_summary(include_title=False) | safe }}
+{{ summary | safe }}
+
+<p>Error in function "{{ last_frame.f_code.co_name }}": {{ last_frame_args | pprint }}</p>
+<pre>{{ last_frame.f_locals | pprint }}</pre>
 
-<p>Error in function "{{ last_frame.function_name }}": {{ last_frame_args | pprint }}</p>
-<pre>{{ last_frame.locals | pprint }}</pre>
 </div>
 
 {% endblock %}
diff --git a/web_view.py b/web_view.py
index 51f341f..5809c6e 100755
--- a/web_view.py
+++ b/web_view.py
@@ -3,6 +3,8 @@
 import inspect
 import json
 import re
+import sys
+import traceback
 from typing import Optional
 
 import flask
@@ -10,7 +12,7 @@ import lxml.html
 import requests
 import werkzeug.exceptions
 from requests_oauthlib import OAuth1Session
-from werkzeug.debug.tbtools import get_current_traceback
+from werkzeug.debug.tbtools import DebugTraceback
 from werkzeug.wrappers import Response
 
 from dab_mechanic import mediawiki_api, wikidata_oauth, wikipedia
@@ -32,14 +34,25 @@ def global_user() -> None:
 
 
 @app.errorhandler(werkzeug.exceptions.InternalServerError)
-def exception_handler(e):
-    tb = get_current_traceback()
-    last_frame = next(frame for frame in reversed(tb.frames) if not frame.is_library)
-    last_frame_args = inspect.getargs(last_frame.code)
+def exception_handler(e: werkzeug.exceptions.InternalServerError) -> tuple[str, int]:
+    """Handle exception."""
+    exec_type, exc_value, current_traceback = sys.exc_info()
+    assert exc_value
+    tb = DebugTraceback(exc_value)
+
+    summary = tb.render_traceback_html(include_title=False)
+    exc_lines = "".join(tb._te.format_exception_only())
+
+    last_frame = list(traceback.walk_tb(current_traceback))[-1][0]
+    last_frame_args = inspect.getargs(last_frame.f_code)
+
     return (
         flask.render_template(
             "show_error.html",
-            tb=tb,
+            plaintext=tb.render_traceback_text(),
+            exception=exc_lines,
+            exception_type=tb._te.exc_type.__name__,
+            summary=summary,
             last_frame=last_frame,
             last_frame_args=last_frame_args,
         ),