b10634f831
CI / update (push) Successful in 39s
Adds prerendered, JS-less, self-contained error pages for nginx error_page use — served directly from /var/www/errors/ when the SvelteKit upstream is unreachable or any nginx-originated 4xx/5xx fires (including the catch-all default_server for unknown hosts). - /errors/[status] (DE default) + /errors/en/[status] (EN), each with a header language toggle linking absolute to bocken.org so the switch works even on unknown-host fallbacks. - httpStatus param matcher restricts entries to 401/403/404/500/ 502/503/504; entries() drives prerender output. - generate-error-quotes.ts looks up curated bilingual references in the existing allioli/drb TSV bibles at prebuild time and writes src/lib/data/errorQuotes.json. - build-error-page.ts (postbuild) inlines all CSS, strips module preloads/scripts, rewrites the home-link to canonical https URL, and emits .html + .gz + .br per status under build/client/errors. - deploy.sh syncs build/client/errors → /var/www/errors with http:http ownership for nginx access.
78 lines
3.3 KiB
TypeScript
78 lines
3.3 KiB
TypeScript
export function getErrorTitle(status: number, isEnglish: boolean): string {
|
|
if (isEnglish) {
|
|
switch (status) {
|
|
case 401: return 'Login Required';
|
|
case 403: return 'Access Denied';
|
|
case 404: return 'Page Not Found';
|
|
case 500: return 'Server Error';
|
|
case 502: return 'Bad Gateway';
|
|
case 503: return 'Service Temporarily Unavailable';
|
|
case 504: return 'Gateway Timeout';
|
|
default: return 'Error';
|
|
}
|
|
}
|
|
switch (status) {
|
|
case 401: return 'Anmeldung erforderlich';
|
|
case 403: return 'Zugriff verweigert';
|
|
case 404: return 'Seite nicht gefunden';
|
|
case 500: return 'Serverfehler';
|
|
case 502: return 'Bad Gateway';
|
|
case 503: return 'Server vorübergehend nicht erreichbar';
|
|
case 504: return 'Gateway-Zeitüberschreitung';
|
|
default: return 'Fehler';
|
|
}
|
|
}
|
|
|
|
export function getErrorDescription(status: number, isEnglish: boolean): string {
|
|
if (isEnglish) {
|
|
switch (status) {
|
|
case 401: return 'You must be logged in to access this page.';
|
|
case 403: return 'You do not have permission for this area.';
|
|
case 404: return 'The requested page could not be found.';
|
|
case 500: return 'An unexpected error occurred. Please try again later.';
|
|
case 502: return 'The site is briefly offline. Please try again in a few minutes.';
|
|
case 503: return 'The site is briefly offline. Please try again in a few minutes.';
|
|
case 504: return 'The upstream is taking too long to respond. Please try again shortly.';
|
|
default: return 'An unexpected error occurred.';
|
|
}
|
|
}
|
|
switch (status) {
|
|
case 401: return 'Du musst angemeldet sein, um auf diese Seite zugreifen zu können.';
|
|
case 403: return 'Du hast keine Berechtigung für diesen Bereich.';
|
|
case 404: return 'Die angeforderte Seite konnte nicht gefunden werden.';
|
|
case 500: return 'Es ist ein unerwarteter Fehler aufgetreten. Bitte versuche es später erneut.';
|
|
case 502: return 'Die Seite ist gerade kurz offline. Bitte in ein paar Minuten erneut probieren.';
|
|
case 503: return 'Die Seite ist gerade kurz offline. Bitte in ein paar Minuten erneut probieren.';
|
|
case 504: return 'Der Server braucht zu lange zum Antworten. Bitte gleich nochmal probieren.';
|
|
default: return 'Es ist ein unerwarteter Fehler aufgetreten.';
|
|
}
|
|
}
|
|
|
|
export interface BibleQuote {
|
|
text: string;
|
|
reference: string;
|
|
}
|
|
|
|
// Generated at prebuild time by scripts/generate-error-quotes.ts from the
|
|
// allioli (DE) + drb (EN) TSV bibles. Curated reference list lives in that
|
|
// script; this JSON is the resolved verse text + display reference.
|
|
import errorQuotesData from '$lib/data/errorQuotes.json';
|
|
const errorQuotes = errorQuotesData as Record<string, { de: BibleQuote; en: BibleQuote }>;
|
|
|
|
export function getErrorBibleQuote(status: number, isEnglish: boolean): BibleQuote | null {
|
|
const entry = errorQuotes[String(status)];
|
|
if (!entry) return null;
|
|
return isEnglish ? entry.en : entry.de;
|
|
}
|
|
|
|
export const errorLabels = {
|
|
login: { en: 'Log in', de: 'Anmelden' },
|
|
tryAgain: { en: 'Try again', de: 'Erneut versuchen' },
|
|
goBack: { en: 'Go back', de: 'Zurück' },
|
|
homepage: { en: 'Homepage', de: 'Startseite' }
|
|
} as const;
|
|
|
|
export function pick(pair: { en: string; de: string }, isEnglish: boolean): string {
|
|
return isEnglish ? pair.en : pair.de;
|
|
}
|