feat(error): friendlier generic error page (LC-552) #517
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/LC-552-friendly-error-page"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Improve the generic error page (LC-552). The report showed the bare "400 / Bad request / invalid or revoked code / Back to home" card and asked to improve its UX.
Context: the specific invite-code 400 in the screenshot was already fixed by LC-544 (#513, merged), which redirects a bad enclave code to a friendly discover banner. That exact string no longer exists in the tree. This PR improves the generic error page itself, which is still shown for every other handler error (403 / 404 / 409 / 413 / 429 / 500 and any other 400).
How
Internalvariant (sqlx / askama / panic text) passesdetail = None, so operator-facing strings never reach the client. It stays logged for operators.A deliberate call on "no raw message"
The picked option leaned toward hiding raw messages. I kept the curated caller reason as a secondary detail line (e.g. "Pin cap reached (max 50)", "foreign_avatar must be a valid URL") rather than blanket-hiding it, because:
Internal) is the real leak vector, and it stays hidden.Net: friendly context always, helpful specific reason when the caller curated one, internal error text never. The detail stays HTML-escaped (Askama) and length-clamped. If you'd rather hide the curated reason too, it's a one-line flip (pass
Nonefor those variants) - say the word.Note (out of scope)
The JSON API (
/api/v1/*) sharesAppError, so on error it renders this HTML page rather than a JSON error body. That predates this PR; worth a follow-up to give the API a JSON error path, but I kept LC-552 focused on the page.Tests
Lib-level (so they run in CI) over
AppError::into_response: BadRequest shows friendly copy + curated detail; Internal never leaks its sqlx/host text; NotFound renders human copy; TooManyRequests keepsRetry-Afterand shows its reason. Fulljust test/just test-saasgreen - existing tests that assert curated messages (pin cap, anti-spam block, bridge SSRF) still pass unchanged.🤖 Generated with Claude Code
https://claude.ai/code/session_016e15V7qtQgNFaK3VNYpwkw