Fix unreachable mobile Settings link and raw error tracebacks
All checks were successful
Deploy / deploy (push) Successful in 2m6s
All checks were successful
Deploy / deploy (push) Successful in 2m6s
Settings lived inside .header-right, which is hidden below 600px, leaving no way to reach it on mobile. It's now a standalone 44x44px button next to the title. Dashboard error cards showed raw Python/urllib3 exception strings. Added a friendly_error() filter that classifies the failure (timeout, connection refused, DNS, auth, 4xx/5xx, TLS) into plain-English copy, with the raw string still available behind a details disclosure. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
9804283396
commit
2e1f8efa33
2 changed files with 133 additions and 16 deletions
35
app.py
35
app.py
|
|
@ -32,6 +32,41 @@ def save_settings(data):
|
|||
|
||||
app = Flask(__name__)
|
||||
app.secret_key = os.environ.get("SECRET_KEY") or secrets.token_hex(32)
|
||||
|
||||
|
||||
def friendly_error(raw, service=""):
|
||||
"""Turn a raw exception string into a short, human-readable cause.
|
||||
|
||||
The service dicts carry str(e) from requests/urllib3, which is useful for
|
||||
debugging but unreadable on the dashboard. Templates render this instead
|
||||
and keep the raw string behind a details disclosure.
|
||||
"""
|
||||
s = str(raw or "")
|
||||
low = s.lower()
|
||||
name = service or "The service"
|
||||
|
||||
if low.strip() == "timeout":
|
||||
return f"{name} took too long to answer and was dropped at the 5s page deadline."
|
||||
if "connecttimeout" in low or "timed out" in low or "read timed out" in low:
|
||||
return f"{name} didn't respond — the connection timed out."
|
||||
if "connection refused" in low or "newconnectionerror" in low:
|
||||
return f"{name} refused the connection — check that it's running and the port is right."
|
||||
if "name or service not known" in low or "nameresolution" in low or "failed to resolve" in low:
|
||||
return f"{name}'s hostname couldn't be resolved — check the host setting."
|
||||
if "no route to host" in low or "network is unreachable" in low:
|
||||
return f"{name} is unreachable from this container — check the network."
|
||||
if "401" in s or "unauthorized" in low or "403" in s or "forbidden" in low:
|
||||
return f"{name} rejected the API key."
|
||||
if "404" in s or "not found" in low:
|
||||
return f"{name} returned 404 — check the URL or base path."
|
||||
if any(code in s for code in ("500", "502", "503", "504")):
|
||||
return f"{name} returned a server error."
|
||||
if "ssl" in low or "certificate" in low:
|
||||
return f"{name}'s TLS handshake failed — check the certificate settings."
|
||||
return f"{name} couldn't be reached."
|
||||
|
||||
|
||||
app.jinja_env.filters["friendly_error"] = friendly_error
|
||||
app.config["SESSION_COOKIE_PATH"] = "/"
|
||||
app.config["SESSION_COOKIE_HTTPONLY"] = True
|
||||
app.config["SESSION_COOKIE_SAMESITE"] = "Lax"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue