← back to Robet Site
round3 item (5): graceful 500 error page — global handler serves styled 500.html for browser GETs (parity with 404), JSON for API; brutalist 500 page
b4b22f44fcac5704e99e2c87c70e0ef834d4b364 · 2026-06-30 02:59:57 -0700 · Steve
Files touched
A public/500.htmlM server.js
Diff
commit b4b22f44fcac5704e99e2c87c70e0ef834d4b364
Author: Steve <steve@designerwallcoverings.com>
Date: Tue Jun 30 02:59:57 2026 -0700
round3 item (5): graceful 500 error page — global handler serves styled 500.html for browser GETs (parity with 404), JSON for API; brutalist 500 page
---
public/500.html | 30 ++++++++++++++++++++++++++++++
server.js | 4 ++++
2 files changed, 34 insertions(+)
diff --git a/public/500.html b/public/500.html
new file mode 100644
index 0000000..7a4894f
--- /dev/null
+++ b/public/500.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <title>500 · ROBERT</title>
+ <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
+ <link rel="stylesheet" href="/styles.css" />
+</head>
+<body>
+ <a class="skip" href="#top">Skip to content</a>
+ <header class="topbar">
+ <a class="logo" href="/">ROBERT</a>
+ <span class="mono" style="text-transform:uppercase">500</span>
+ </header>
+ <main id="top" tabindex="-1">
+ <section style="min-height:70vh; display:flex; flex-direction:column; justify-content:center;">
+ <span class="kicker">/ our fault</span>
+ <h1 class="sec-h" style="font-size:clamp(56px,18vw,180px); line-height:.85;">500</h1>
+ <p class="mono" style="font-weight:700; font-size:20px; margin-bottom:24px;">
+ Something broke on our end. It's not you. Try again in a moment.
+ </p>
+ <div>
+ <a class="cta" href="/">← Back to start</a>
+ <a class="cta" href="/#booking" style="margin-left:12px;">Book a meeting →</a>
+ </div>
+ </section>
+ </main>
+</body>
+</html>
diff --git a/server.js b/server.js
index dd52d82..0b859b7 100644
--- a/server.js
+++ b/server.js
@@ -164,6 +164,10 @@ app.use((err, req, res, _next) => {
const code = err.status || err.statusCode || 500;
console.error('route error:', code, err && err.message);
if (res.headersSent) return;
+ // browser navigations get a styled page (parity with 404); APIs/fetch get JSON
+ if (code >= 500 && req.accepts('html') && req.method === 'GET') {
+ return res.status(code).sendFile(path.join(__dirname, 'public', '500.html'));
+ }
res.status(code).json({ ok: false, error: code === 400 ? 'Bad request' : 'Server error' });
});
← 46ee0e0 loop ledger: round3 item (3) done + deployed
·
back to Robet Site
·
loop ledger: round3 item (5) done + deployed 9c3de8a →