Skip to content

feat(pages): Redesign the error pages - #581

Merged
balamurali27 merged 2 commits into
developfrom
new-error-pages
Aug 18, 2026
Merged

feat(pages): Redesign the error pages#581
balamurali27 merged 2 commits into
developfrom
new-error-pages

Conversation

@balamurali27

Copy link
Copy Markdown
Contributor

What

Redesigns all eight error pages and points the 500 page at the bench's web.error.log.

Before, each page was a logo header over a shadowed card, with the docs link styled as an inline 📄 pseudo-button. Now every page is one shared layout: icon, heading, error line, optional docs button, owner footer.

Page Status Icon
bad_gateway.html 502 red
gateway_timeout.html 504 red
internal_server_error.html 500 red
exceeded.html 429 amber
suspended.html / suspended_saas.html 402 amber
deactivated.html 503 amber
home.html neutral

Visited links

Text links carry the plain-html visited purple. The rule is scoped a:not(.button):visited deliberately: a bare a:visited has specificity (0,1,1) and outranks .button's own color: #fff at (0,1,0), which repaints the button's white label purple. The button itself has no visited state — :visited reaches only a few colour properties, never a button's label, and Chrome has partitioned it per top-level site and frame origin since 136.

The 500 page

The traceback for a 500 lands in the bench's web.error.log, so the footer now links straight to /dashboard/benches/<bench>/logs/web.error.log instead of the site's dashboard root.

One static page is shared by every bench on the server, so the page ships __BENCH_NAME__ and the per-bench nginx config substitutes it:

location = /internal_server_error.html {
	root {{ error_pages_directory }};
	sub_filter '__BENCH_NAME__' '{{ bench_name }}';
}

This works because the 500 interception injects <iframe src="/internal_server_error.html"> — a relative URL — so the iframe request carries the failing site's Host and resolves through its own bench's server block.

A side effect worth having: this page no longer needs the window.location.hostname script, making it the one error page immune to the custom-domain problem, where hostname is not the site's name once a custom domain is in front of it. The other pages still have that pre-existing issue.

Also drops the Google Fonts <link> an earlier attempt carried — an external font request would hang on the very networks these pages appear on.

Testing

Verified end to end against a local Frappe Cloud install with a real bench on f1.local.frappe.dev:

  • nginx substitution over HTTP — the same file (one md5) served through two hosts returned bench-0004-000023-f1 and bench-0004-000022-f1 respectively
  • press.api.bench.log returned {'web.error.log': ...} through the full path: permission check, release-group check, circuit breaker, live agent call
  • LogPage.vue derives the release group as bench-${name.split('-')[1]}; confirmed against real records (bench-0004-000023-f1bench-0004)
  • both template branches (standalone and non-standalone) render the sub_filter correctly

agent/tests/test_pages.py covers the invariants that would silently break a page: no external resources, the scoped visited rule, dashboard links paired with their rewrite script, and every __BENCH_NAME__ matched by a sub_filter in each of its nginx location blocks.

🤖 Generated with Claude Code

balamurali27 and others added 2 commits August 16, 2026 10:22
Replace the logo header and shadowed card with a centred icon, heading,
error line, optional docs button and an owner footer. Every page shares
one stylesheet; nginx serves them as flat files, so a shared css file is
not reachable from the 500 page's iframe.

Text links carry the plain-html visited purple. The rule is scoped with
:not(.button), because a bare a:visited outranks the button's own colour
and repaints its white label purple.

Drop the Google Fonts link the earlier attempt carried. An external font
request would hang on the very networks these pages appear on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The traceback for a 500 lands in the bench's web.error.log, so link
straight to it instead of the site's dashboard root.

One static page is shared by every bench on the server, so the page
ships __BENCH_NAME__ and the per-bench nginx config substitutes it. That
also drops the hostname script from this page, which means it is the one
error page immune to the custom domain problem: window.location.hostname
is not the site's name once a custom domain is in front of it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@mergify

mergify Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@greptile-apps

greptile-apps Bot commented Aug 16, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

The PR appears safe to merge with no actionable defects identified.

The redesigned pages preserve their nginx serving paths, and the new substituted bench log URL matches the consuming Press route and log-loading contract.

Reviews (1): Last reviewed commit: "feat(pages): Point the 500 page at the b..." | Re-trigger Greptile

@balamurali27
balamurali27 merged commit a371430 into develop Aug 18, 2026
6 checks passed
@balamurali27
balamurali27 deleted the new-error-pages branch August 18, 2026 10:18
balamurali27 added a commit that referenced this pull request Aug 18, 2026
Mergify left the conflict markers in the branch. Each conflict is the same
dashboard-link script; keep the redesigned version from #581.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
balamurali27 added a commit that referenced this pull request Aug 18, 2026
feat(pages): Redesign the error pages (backport #581)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant