Suggestions

This commit is contained in:
Adam Hopkins 2023-02-06 10:05:51 +02:00
parent 7491d567a3
commit 47b2459811
No known key found for this signature in database
GPG Key ID: 9F85EE6C807303FB
3 changed files with 115 additions and 24 deletions

View File

@ -1,16 +1,30 @@
from .base import BasePage from typing import Any, Mapping
from sanic.request import Request
from contextlib import suppress
from html5tagger import E
from tracerite import html_traceback, inspector
import tracerite.html import tracerite.html
from html5tagger import E
from tracerite import html_traceback, inspector
from sanic.request import Request
from .base import BasePage
# Avoid showing the request in the traceback variable inspectors # Avoid showing the request in the traceback variable inspectors
inspector.blacklist_types += Request, inspector.blacklist_types += (Request,)
class ErrorPage(BasePage): class ErrorPage(BasePage):
STYLE_APPEND = tracerite.html.style STYLE_APPEND = tracerite.html.style
def __init__(self, title: str, text: str, request: Request, exc: Exception, full: bool) -> None:
def __init__(
self,
title: str,
text: str,
request: Request,
exc: Exception,
full: bool,
) -> None:
super().__init__() super().__init__()
# Internal server errors come with the text of the exception, which we don't want to show to the user. # Internal server errors come with the text of the exception, which we don't want to show to the user.
# FIXME: This needs to be done some place else but I am not digging into that now. # FIXME: This needs to be done some place else but I am not digging into that now.
@ -35,26 +49,53 @@ class ErrorPage(BasePage):
route_name = "[route not found]" route_name = "[route not found]"
with self.doc.main: with self.doc.main:
self.doc.h1(f"⚠️ {self.title}").p(self.text) self.doc.h1(f"⚠️ {self.title}").p(self.text)
context = getattr(self.exc, "context", None) or {} # Show context details if available on the exception
if debug: context = getattr(self.exc, "context", None)
context.update(getattr(self.exc, "extra", None) or {})
# Show context and extra details if available on the exception
if context: if context:
# Printing values may easily cause a new exception, so suppress it self._key_value_table(
with self.doc.table(id="exception-context"), suppress(Exception): "Exception context", "exception-context", context
for k, v in context.items(): )
self.doc.tr.td(k).td(v)
if not debug: if not debug:
return return
# Show additional details in debug mode, open by default for 500 errors # Show additional details in debug mode,
# open by default for 500 errors
with self.doc.details(open=self.full, class_="smalltext"): with self.doc.details(open=self.full, class_="smalltext"):
self.doc.summary("Details for developers (Sanic debug mode only)") # Show extra details if available on the exception
extra = getattr(self.exc, "extra", None)
if extra:
self._key_value_table(
"Exception extra data", "exception-extra", extra
)
self.doc.summary(
"Details for developers (Sanic debug mode only)"
)
if self.exc: if self.exc:
self.doc.h2(f"Exception in {route_name}:") self.doc.h2(f"Exception in {route_name}:")
# skip_outmost=1 to hide Sanic.handle_request # skip_outmost=1 to hide Sanic.handle_request
self.doc(html_traceback(self.exc, skip_outmost=1, include_js_css=False)) self.doc(
html_traceback(
self.exc, skip_outmost=1, include_js_css=False
)
)
self.doc.h2(f"{self.request.method} {self.request.path}") self._key_value_table(
with self.doc.table(id="request-headers"): f"{self.request.method} {self.request.path}",
for k, v in self.request.headers.items(): "request-headers",
self.doc.tr.td(f"{k}:", class_="nobr").td(v) self.request.headers,
)
def _key_value_table(
self, title: str, table_id: str, data: Mapping[str, Any]
) -> None:
with self.doc.table(id=table_id, class_="key-value-table"):
self.doc.caption(title)
for key, value in data.items():
try:
self.doc.tr.td(key, class_="nobr key").td(value)
# Printing values may cause a new exception, so suppress it
except Exception:
self.doc.tr.td(key, class_="nobr key").td(
E.em("Unable to display value")
)

View File

@ -1,4 +1,3 @@
/** BasePage **/ /** BasePage **/
html { html {
font: 16px sans-serif; font: 16px sans-serif;
@ -9,6 +8,7 @@ html {
body { body {
margin: 0; margin: 0;
font-size: 1.25rem; font-size: 1.25rem;
--accent: #ff0d68;
} }
body>* { body>* {

View File

@ -1,2 +1,52 @@
/** ErrorPage **/ /** ErrorPage **/
summary { color: #888; } summary {
color: #888;
}
.tracerite {
/* --color-var: var(--accent);
--color-val: #ff0; */
--color-type: var(--accent);
}
.key-value-table {
margin: 2rem 0;
border-collapse: collapse;
}
.key-value-table caption {
caption-side: top;
text-align: left;
font-size: 1.25rem;
font-weight: 700;
padding-bottom: 0.5rem;
}
.key-value-table td {
font-size: 1rem;
font-family: monospace;
border: 1px solid #888;
padding: 0.25rem;
}
.key-value-table .key {
color: var(--accent)
}
mark {
position: relative;
}
mark[data-symbol="💣"]::before {
content: "Exception raised";
display: none;
position: absolute;
top: -1.25em;
right: 0;
padding: 0.25em;
background-color: var(--accent);
}
mark[data-symbol="💣"]:hover::before {
display: block;
}