From ad154bf91473cb891584b6f4251e17de9cd8d7de Mon Sep 17 00:00:00 2001 From: Alexander Bocken Date: Mon, 20 Apr 2026 22:39:04 +0200 Subject: [PATCH] fix(errors): surface Bible verses on section error pages SvelteKit's handleError hook is skipped for expected `error()` throws, so verses set there never reached `$page.error` for server-thrown 404s and auth denials. Introduce `errorWithVerse()` in `$lib/server/errorQuote` that fetches a random verse first, then throws `error(status, body)` with `{ message, bibleQuote, lang }`, making the quote available in every `SectionError`. Convert all page load throws (catchalls, layout validators, calendar, prayers, recipes, fitness, cospend, admin) and hooks.server auth gates to the helper. Add `src/error.html` as a branded last-resort fallback. --- package.json | 2 +- src/error.html | 145 ++++++++++++++++++ src/hooks.server.ts | 80 ++++------ src/lib/server/errorQuote.ts | 34 ++++ .../[...rest]/+page.server.ts | 5 + .../[...rest]/+page.ts | 5 - .../dash/+page.server.ts | 13 +- .../payments/+page.server.ts | 5 +- .../payments/view/[id]/+page.server.ts | 7 +- .../[faithLang=faithLang]/+error.svelte | 9 +- .../[faithLang=faithLang]/+layout.server.ts | 6 +- .../[...rest]/+page.server.ts | 5 + .../[faithLang=faithLang]/[...rest]/+page.ts | 5 - .../[calendar=calendarLang]/+page.server.ts | 7 +- .../[[dd=calendarDay]]/+page.server.ts | 11 +- .../[dd=calendarDay]/+page.server.ts | 15 +- .../[prayer]/+page.server.ts | 3 +- .../[recipeLang=recipeLang]/+error.svelte | 2 +- .../[recipeLang=recipeLang]/+layout.server.ts | 6 +- .../[...rest]/+page.server.ts | 5 + .../[...rest]/+page.ts | 5 - .../[name]/+page.server.ts | 5 +- .../admin/alt-text-generator/+page.server.ts | 7 +- .../admin/image-colors/+page.server.ts | 7 +- .../admin/untranslated/+page.server.ts | 5 +- .../administration/+page.server.ts | 7 +- src/routes/fitness/[...rest]/+page.server.ts | 5 + src/routes/fitness/[...rest]/+page.ts | 5 - .../[id]/+page.server.ts | 4 +- .../[id]/+page.server.ts | 6 +- .../food/[source]/[id]/+page.server.ts | 16 +- src/routes/tasks/[...rest]/+page.server.ts | 5 + src/routes/tasks/[...rest]/+page.ts | 5 - 33 files changed, 311 insertions(+), 141 deletions(-) create mode 100644 src/error.html create mode 100644 src/lib/server/errorQuote.ts create mode 100644 src/routes/[cospendRoot=cospendRoot]/[...rest]/+page.server.ts delete mode 100644 src/routes/[cospendRoot=cospendRoot]/[...rest]/+page.ts create mode 100644 src/routes/[faithLang=faithLang]/[...rest]/+page.server.ts delete mode 100644 src/routes/[faithLang=faithLang]/[...rest]/+page.ts create mode 100644 src/routes/[recipeLang=recipeLang]/[...rest]/+page.server.ts delete mode 100644 src/routes/[recipeLang=recipeLang]/[...rest]/+page.ts create mode 100644 src/routes/fitness/[...rest]/+page.server.ts delete mode 100644 src/routes/fitness/[...rest]/+page.ts create mode 100644 src/routes/tasks/[...rest]/+page.server.ts delete mode 100644 src/routes/tasks/[...rest]/+page.ts diff --git a/package.json b/package.json index a4dbbe77..d4dc3895 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "homepage", - "version": "1.37.0", + "version": "1.37.1", "private": true, "type": "module", "scripts": { diff --git a/src/error.html b/src/error.html new file mode 100644 index 00000000..eb9e9650 --- /dev/null +++ b/src/error.html @@ -0,0 +1,145 @@ + + + + + + + + %sveltekit.status% — Error + + + + +
+
+
Error
+ +

%sveltekit.error.message%

+

+ An unexpected error occurred while rendering this page. +

+ +
+
+ + diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 8a0e8d0c..498bad61 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -1,10 +1,10 @@ import type { Handle, HandleServerError } from "@sveltejs/kit" import { redirect } from "@sveltejs/kit" -import { error } from "@sveltejs/kit" import { sequence } from "@sveltejs/kit/hooks" import * as auth from "./auth" import { initializeScheduler } from "./lib/server/scheduler" import { dbConnect } from "./utils/db" +import { errorWithVerse, getRandomVerse } from "$lib/server/errorQuote" // Initialize database connection on server startup console.log('🚀 Server starting - initializing database connection...'); @@ -21,27 +21,26 @@ await dbConnect().then(() => { async function authorization({ event, resolve }: Parameters[0]) { const session = await event.locals.auth(); event.locals.session = session; + const { fetch, url } = event; // Protect rezepte routes - if (event.url.pathname.startsWith('/rezepte/edit') || event.url.pathname.startsWith('/rezepte/add')) { + if (url.pathname.startsWith('/rezepte/edit') || url.pathname.startsWith('/rezepte/add')) { if (!session) { - // Preserve the original URL the user was trying to access - const callbackUrl = encodeURIComponent(event.url.pathname + event.url.search); + const callbackUrl = encodeURIComponent(url.pathname + url.search); redirect(303, `/login?callbackUrl=${callbackUrl}`); } else if (!session.user?.groups?.includes('rezepte_users')) { - error(403, { - message: 'Zugriff verweigert. Du hast keine Berechtigung für diesen Bereich. Falls du glaubst, dass dies ein Fehler ist, wende dich bitte an Alexander.' - }); + await errorWithVerse(fetch, url.pathname, 403, + 'Zugriff verweigert. Du hast keine Berechtigung für diesen Bereich. Falls du glaubst, dass dies ein Fehler ist, wende dich bitte an Alexander.'); } } // Protect cospend routes and API endpoints - if (event.url.pathname.startsWith('/cospend') || event.url.pathname.startsWith('/expenses') || event.url.pathname.startsWith('/api/cospend')) { + if (url.pathname.startsWith('/cospend') || url.pathname.startsWith('/expenses') || url.pathname.startsWith('/api/cospend')) { if (!session) { // Allow share-token access to shopping list routes - const isShoppingRoute = event.url.pathname.startsWith('/cospend/list') || event.url.pathname.startsWith('/expenses/list') || event.url.pathname.startsWith('/api/cospend/list'); - const shareToken = event.url.searchParams.get('token'); + const isShoppingRoute = url.pathname.startsWith('/cospend/list') || url.pathname.startsWith('/expenses/list') || url.pathname.startsWith('/api/cospend/list'); + const shareToken = url.searchParams.get('token'); if (isShoppingRoute && shareToken) { const { validateShareToken } = await import('$lib/server/shoppingAuth'); if (await validateShareToken(shareToken)) { @@ -50,49 +49,42 @@ async function authorization({ event, resolve }: Parameters[0]) { } // For API routes, return 401 instead of redirecting - if (event.url.pathname.startsWith('/api/cospend')) { - error(401, { - message: 'Anmeldung erforderlich. Du musst angemeldet sein, um auf diesen Bereich zugreifen zu können.' - }); + if (url.pathname.startsWith('/api/cospend')) { + await errorWithVerse(fetch, url.pathname, 401, + 'Anmeldung erforderlich. Du musst angemeldet sein, um auf diesen Bereich zugreifen zu können.'); } // For page routes, redirect to login - const callbackUrl = encodeURIComponent(event.url.pathname + event.url.search); + const callbackUrl = encodeURIComponent(url.pathname + url.search); redirect(303, `/login?callbackUrl=${callbackUrl}`); } else if (!session.user?.groups?.includes('cospend')) { - error(403, { - message: 'Zugriff verweigert. Du hast keine Berechtigung für diesen Bereich. Falls du glaubst, dass dies ein Fehler ist, wende dich bitte an Alexander.' - }); + await errorWithVerse(fetch, url.pathname, 403, + 'Zugriff verweigert. Du hast keine Berechtigung für diesen Bereich. Falls du glaubst, dass dies ein Fehler ist, wende dich bitte an Alexander.'); } } // Protect tasks routes and API endpoints - if (event.url.pathname.startsWith('/tasks') || event.url.pathname.startsWith('/api/tasks')) { + if (url.pathname.startsWith('/tasks') || url.pathname.startsWith('/api/tasks')) { if (!session) { - if (event.url.pathname.startsWith('/api/tasks')) { - error(401, { - message: 'Anmeldung erforderlich.' - }); + if (url.pathname.startsWith('/api/tasks')) { + await errorWithVerse(fetch, url.pathname, 401, 'Anmeldung erforderlich.'); } - const callbackUrl = encodeURIComponent(event.url.pathname + event.url.search); + const callbackUrl = encodeURIComponent(url.pathname + url.search); redirect(303, `/login?callbackUrl=${callbackUrl}`); } else if (!session.user?.groups?.includes('task_users')) { - error(403, { - message: 'Zugriff verweigert. Du hast keine Berechtigung für diesen Bereich. Falls du glaubst, dass dies ein Fehler ist, wende dich bitte an Alexander.' - }); + await errorWithVerse(fetch, url.pathname, 403, + 'Zugriff verweigert. Du hast keine Berechtigung für diesen Bereich. Falls du glaubst, dass dies ein Fehler ist, wende dich bitte an Alexander.'); } } // Protect fitness routes and API endpoints - if (event.url.pathname.startsWith('/fitness') || event.url.pathname.startsWith('/api/fitness')) { + if (url.pathname.startsWith('/fitness') || url.pathname.startsWith('/api/fitness')) { if (!session) { - if (event.url.pathname.startsWith('/api/fitness')) { - error(401, { - message: 'Authentication required.' - }); + if (url.pathname.startsWith('/api/fitness')) { + await errorWithVerse(fetch, url.pathname, 401, 'Authentication required.'); } - const callbackUrl = encodeURIComponent(event.url.pathname + event.url.search); + const callbackUrl = encodeURIComponent(url.pathname + url.search); redirect(303, `/login?callbackUrl=${callbackUrl}`); } } @@ -101,32 +93,14 @@ async function authorization({ event, resolve }: Parameters[0]) { return resolve(event); } -// Bible verse functionality for error pages -async function getRandomVerse(fetch: typeof globalThis.fetch, pathname: string): Promise<{ text: string; reference: string } | null> { - const isEnglish = pathname.startsWith('/faith/') || pathname.startsWith('/recipes/'); - const endpoint = isEnglish ? '/api/faith/bibel/zufallszitat' : '/api/glaube/bibel/zufallszitat'; - try { - const response = await fetch(endpoint); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - return await response.json(); - } catch (err) { - console.error('Error getting random verse:', err); - return null; - } -} - export const handleError: HandleServerError = async ({ error, event, status, message }) => { console.error('Error occurred:', { error, status, message, url: event.url.pathname }); - - // Add Bible verse to error context - const bibleQuote = await getRandomVerse(event.fetch, event.url.pathname); + const bibleQuote = await getRandomVerse(event.fetch, event.url.pathname); const isEnglish = event.url.pathname.startsWith('/faith/') || event.url.pathname.startsWith('/recipes/'); return { - message: message, + message, bibleQuote, lang: isEnglish ? 'en' : 'de' }; diff --git a/src/lib/server/errorQuote.ts b/src/lib/server/errorQuote.ts new file mode 100644 index 00000000..15d08599 --- /dev/null +++ b/src/lib/server/errorQuote.ts @@ -0,0 +1,34 @@ +import { error } from '@sveltejs/kit'; + +type Fetch = typeof globalThis.fetch; + +function detectLang(pathname: string): 'en' | 'de' { + return pathname.startsWith('/faith/') || pathname.startsWith('/recipes/') ? 'en' : 'de'; +} + +export async function getRandomVerse( + fetch: Fetch, + pathname: string +): Promise<{ text: string; reference: string } | null> { + const endpoint = + detectLang(pathname) === 'en' + ? '/api/faith/bibel/zufallszitat' + : '/api/glaube/bibel/zufallszitat'; + try { + const res = await fetch(endpoint); + if (!res.ok) return null; + return await res.json(); + } catch { + return null; + } +} + +export async function errorWithVerse( + fetch: Fetch, + pathname: string, + status: number, + message = '' +): Promise { + const bibleQuote = await getRandomVerse(fetch, pathname); + error(status, { message, bibleQuote, lang: detectLang(pathname) }); +} diff --git a/src/routes/[cospendRoot=cospendRoot]/[...rest]/+page.server.ts b/src/routes/[cospendRoot=cospendRoot]/[...rest]/+page.server.ts new file mode 100644 index 00000000..edb97404 --- /dev/null +++ b/src/routes/[cospendRoot=cospendRoot]/[...rest]/+page.server.ts @@ -0,0 +1,5 @@ +import type { PageServerLoad } from './$types'; +import { errorWithVerse } from '$lib/server/errorQuote'; + +export const load: PageServerLoad = ({ fetch, url }) => + errorWithVerse(fetch, url.pathname, 404, 'Not found'); diff --git a/src/routes/[cospendRoot=cospendRoot]/[...rest]/+page.ts b/src/routes/[cospendRoot=cospendRoot]/[...rest]/+page.ts deleted file mode 100644 index 8ea3fd8e..00000000 --- a/src/routes/[cospendRoot=cospendRoot]/[...rest]/+page.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { error } from '@sveltejs/kit'; - -export const load = () => { - error(404, 'Not found'); -}; diff --git a/src/routes/[cospendRoot=cospendRoot]/dash/+page.server.ts b/src/routes/[cospendRoot=cospendRoot]/dash/+page.server.ts index 4cf21e28..4eaf1bbf 100644 --- a/src/routes/[cospendRoot=cospendRoot]/dash/+page.server.ts +++ b/src/routes/[cospendRoot=cospendRoot]/dash/+page.server.ts @@ -1,9 +1,10 @@ import type { PageServerLoad } from './$types'; -import { redirect, error } from '@sveltejs/kit'; +import { redirect } from '@sveltejs/kit'; +import { errorWithVerse } from '$lib/server/errorQuote'; -export const load: PageServerLoad = async ({ locals, fetch }) => { +export const load: PageServerLoad = async ({ locals, fetch, url }) => { const session = await locals.auth(); - + if (!session) { throw redirect(302, '/login'); } @@ -14,11 +15,11 @@ export const load: PageServerLoad = async ({ locals, fetch }) => { fetch('/api/cospend/balance'), fetch('/api/cospend/debts') ]); - + if (!balanceResponse.ok) { throw new Error('Failed to fetch balance'); } - + if (!debtResponse.ok) { throw new Error('Failed to fetch debt data'); } @@ -33,6 +34,6 @@ export const load: PageServerLoad = async ({ locals, fetch }) => { }; } catch (e) { console.error('Error loading dashboard data:', e); - throw error(500, 'Failed to load dashboard data'); + await errorWithVerse(fetch, url.pathname, 500, 'Failed to load dashboard data'); } }; \ No newline at end of file diff --git a/src/routes/[cospendRoot=cospendRoot]/payments/+page.server.ts b/src/routes/[cospendRoot=cospendRoot]/payments/+page.server.ts index 7e767624..5ca0121b 100644 --- a/src/routes/[cospendRoot=cospendRoot]/payments/+page.server.ts +++ b/src/routes/[cospendRoot=cospendRoot]/payments/+page.server.ts @@ -1,5 +1,6 @@ import type { PageServerLoad } from './$types'; -import { redirect, error } from '@sveltejs/kit'; +import { redirect } from '@sveltejs/kit'; +import { errorWithVerse } from '$lib/server/errorQuote'; export const load: PageServerLoad = async ({ locals, fetch, url }) => { const session = await locals.auth(); @@ -29,6 +30,6 @@ export const load: PageServerLoad = async ({ locals, fetch, url }) => { }; } catch (e) { console.error('Error loading payments data:', e); - throw error(500, 'Failed to load payments data'); + await errorWithVerse(fetch, url.pathname, 500, 'Failed to load payments data'); } }; \ No newline at end of file diff --git a/src/routes/[cospendRoot=cospendRoot]/payments/view/[id]/+page.server.ts b/src/routes/[cospendRoot=cospendRoot]/payments/view/[id]/+page.server.ts index acc719fe..6462d852 100644 --- a/src/routes/[cospendRoot=cospendRoot]/payments/view/[id]/+page.server.ts +++ b/src/routes/[cospendRoot=cospendRoot]/payments/view/[id]/+page.server.ts @@ -1,7 +1,8 @@ import type { PageServerLoad } from './$types'; -import { redirect, error } from '@sveltejs/kit'; +import { redirect } from '@sveltejs/kit'; +import { errorWithVerse } from '$lib/server/errorQuote'; -export const load: PageServerLoad = async ({ locals, params, fetch }) => { +export const load: PageServerLoad = async ({ locals, params, fetch, url }) => { const session = await locals.auth(); if (!session) { @@ -23,6 +24,6 @@ export const load: PageServerLoad = async ({ locals, params, fetch }) => { }; } catch (e) { console.error('Error loading payment data:', e); - throw error(500, 'Failed to load payment data'); + await errorWithVerse(fetch, url.pathname, 500, 'Failed to load payment data'); } }; \ No newline at end of file diff --git a/src/routes/[faithLang=faithLang]/+error.svelte b/src/routes/[faithLang=faithLang]/+error.svelte index a62f50f2..7e953d48 100644 --- a/src/routes/[faithLang=faithLang]/+error.svelte +++ b/src/routes/[faithLang=faithLang]/+error.svelte @@ -1,13 +1,18 @@ diff --git a/src/routes/[faithLang=faithLang]/+layout.server.ts b/src/routes/[faithLang=faithLang]/+layout.server.ts index 786101d6..16956502 100644 --- a/src/routes/[faithLang=faithLang]/+layout.server.ts +++ b/src/routes/[faithLang=faithLang]/+layout.server.ts @@ -1,10 +1,10 @@ import type { LayoutServerLoad } from "./$types" -import { error } from "@sveltejs/kit"; +import { errorWithVerse } from "$lib/server/errorQuote" -export const load : LayoutServerLoad = async ({locals, params}) => { +export const load : LayoutServerLoad = async ({locals, params, fetch, url}) => { // Validate faithLang parameter if (params.faithLang !== 'glaube' && params.faithLang !== 'faith' && params.faithLang !== 'fides') { - throw error(404, 'Not found'); + await errorWithVerse(fetch, url.pathname, 404, 'Not found'); } const lang = params.faithLang === 'faith' ? 'en' : params.faithLang === 'fides' ? 'la' : 'de'; diff --git a/src/routes/[faithLang=faithLang]/[...rest]/+page.server.ts b/src/routes/[faithLang=faithLang]/[...rest]/+page.server.ts new file mode 100644 index 00000000..edb97404 --- /dev/null +++ b/src/routes/[faithLang=faithLang]/[...rest]/+page.server.ts @@ -0,0 +1,5 @@ +import type { PageServerLoad } from './$types'; +import { errorWithVerse } from '$lib/server/errorQuote'; + +export const load: PageServerLoad = ({ fetch, url }) => + errorWithVerse(fetch, url.pathname, 404, 'Not found'); diff --git a/src/routes/[faithLang=faithLang]/[...rest]/+page.ts b/src/routes/[faithLang=faithLang]/[...rest]/+page.ts deleted file mode 100644 index 8ea3fd8e..00000000 --- a/src/routes/[faithLang=faithLang]/[...rest]/+page.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { error } from '@sveltejs/kit'; - -export const load = () => { - error(404, 'Not found'); -}; diff --git a/src/routes/[faithLang=faithLang]/[calendar=calendarLang]/+page.server.ts b/src/routes/[faithLang=faithLang]/[calendar=calendarLang]/+page.server.ts index b90179c6..d86965e9 100644 --- a/src/routes/[faithLang=faithLang]/[calendar=calendarLang]/+page.server.ts +++ b/src/routes/[faithLang=faithLang]/[calendar=calendarLang]/+page.server.ts @@ -1,10 +1,11 @@ -import { error, redirect } from '@sveltejs/kit'; +import { redirect } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; import { expectedSlug } from './calendarI18n'; +import { errorWithVerse } from '$lib/server/errorQuote'; -export const load: PageServerLoad = async ({ params, url }) => { +export const load: PageServerLoad = async ({ params, url, fetch }) => { const slug = expectedSlug(params.faithLang); - if (slug === null) throw error(404, 'Not found'); + if (slug === null) await errorWithVerse(fetch, url.pathname, 404, 'Not found'); if (params.calendar !== slug) { throw redirect(307, `/${params.faithLang}/${slug}`); } diff --git a/src/routes/[faithLang=faithLang]/[calendar=calendarLang]/[rite=calendarRite]/[[yyyy=calendarYear]]/[[mm=calendarMonth]]/[[dd=calendarDay]]/+page.server.ts b/src/routes/[faithLang=faithLang]/[calendar=calendarLang]/[rite=calendarRite]/[[yyyy=calendarYear]]/[[mm=calendarMonth]]/[[dd=calendarDay]]/+page.server.ts index d3c2e653..3e6b4e5c 100644 --- a/src/routes/[faithLang=faithLang]/[calendar=calendarLang]/[rite=calendarRite]/[[yyyy=calendarYear]]/[[mm=calendarMonth]]/[[dd=calendarDay]]/+page.server.ts +++ b/src/routes/[faithLang=faithLang]/[calendar=calendarLang]/[rite=calendarRite]/[[yyyy=calendarYear]]/[[mm=calendarMonth]]/[[dd=calendarDay]]/+page.server.ts @@ -1,5 +1,6 @@ -import { error, redirect } from '@sveltejs/kit'; +import { redirect } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; +import { errorWithVerse } from '$lib/server/errorQuote'; import { DEFAULT_DIOCESE_1962, DEFAULT_DIOCESE_1969, @@ -29,9 +30,9 @@ export type { YearDay } from '$lib/calendarTypes'; -export const load: PageServerLoad = async ({ params, url, locals }) => { +export const load: PageServerLoad = async ({ params, url, locals, fetch }) => { const slug = expectedSlug(params.faithLang); - if (slug === null) throw error(404, 'Not found'); + if (slug === null) await errorWithVerse(fetch, url.pathname, 404, 'Not found'); if (params.calendar !== slug) { throw redirect(307, `/${params.faithLang}/${slug}`); } @@ -52,7 +53,7 @@ export const load: PageServerLoad = async ({ params, url, locals }) => { // Reject mm without yyyy, dd without yyyy+mm. Sveltekit optional routes let // gaps through so we normalize here. if ((params.mm && !params.yyyy) || (params.dd && !params.mm)) { - throw error(404, 'Not found'); + await errorWithVerse(fetch, url.pathname, 404, 'Not found'); } const today = new Date(); @@ -92,7 +93,7 @@ export const load: PageServerLoad = async ({ params, url, locals }) => { const daysInMonth = new Date(year, month + 1, 0).getDate(); if (params.dd) { const ddNum = Number(params.dd); - if (ddNum < 1 || ddNum > daysInMonth) throw error(404, 'Not found'); + if (ddNum < 1 || ddNum > daysInMonth) await errorWithVerse(fetch, url.pathname, 404, 'Not found'); } // Tentative selectedIso used only for the LY rollover decision. The real // selectedIso is recomputed after monthDays below (same logic, now on the diff --git a/src/routes/[faithLang=faithLang]/[calendar=calendarLang]/[rite=calendarRite]/detail/[yyyy=calendarYear]/[mm=calendarMonth]/[dd=calendarDay]/+page.server.ts b/src/routes/[faithLang=faithLang]/[calendar=calendarLang]/[rite=calendarRite]/detail/[yyyy=calendarYear]/[mm=calendarMonth]/[dd=calendarDay]/+page.server.ts index 1aeec965..ef0c9030 100644 --- a/src/routes/[faithLang=faithLang]/[calendar=calendarLang]/[rite=calendarRite]/detail/[yyyy=calendarYear]/[mm=calendarMonth]/[dd=calendarDay]/+page.server.ts +++ b/src/routes/[faithLang=faithLang]/[calendar=calendarLang]/[rite=calendarRite]/detail/[yyyy=calendarYear]/[mm=calendarMonth]/[dd=calendarDay]/+page.server.ts @@ -1,5 +1,6 @@ -import { error, redirect } from '@sveltejs/kit'; +import { redirect } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; +import { errorWithVerse } from '$lib/server/errorQuote'; import { DEFAULT_DIOCESE_1962, DEFAULT_DIOCESE_1969, @@ -13,9 +14,9 @@ import { } from '../../../../../calendarI18n'; import { getYear, getYear1962, isoFor } from '$lib/server/liturgicalCalendar'; -export const load: PageServerLoad = async ({ params, url, locals }) => { +export const load: PageServerLoad = async ({ params, url, locals, fetch }) => { const slug = expectedSlug(params.faithLang); - if (slug === null) throw error(404, 'Not found'); + if (slug === null) await errorWithVerse(fetch, url.pathname, 404, 'Not found'); if (params.calendar !== slug) { throw redirect(307, `/${params.faithLang}/${slug}`); } @@ -38,10 +39,10 @@ export const load: PageServerLoad = async ({ params, url, locals }) => { const month = Number(params.mm) - 1; const day = Number(params.dd); - if (!Number.isFinite(year) || year < minYear || year > 2100) throw error(404, 'Not found'); - if (!Number.isFinite(month) || month < 0 || month > 11) throw error(404, 'Not found'); + if (!Number.isFinite(year) || year < minYear || year > 2100) await errorWithVerse(fetch, url.pathname, 404, 'Not found'); + if (!Number.isFinite(month) || month < 0 || month > 11) await errorWithVerse(fetch, url.pathname, 404, 'Not found'); const daysInMonth = new Date(year, month + 1, 0).getDate(); - if (!Number.isFinite(day) || day < 1 || day > daysInMonth) throw error(404, 'Not found'); + if (!Number.isFinite(day) || day < 1 || day > daysInMonth) await errorWithVerse(fetch, url.pathname, 404, 'Not found'); const iso = isoFor(year, month, day); const yearMap = @@ -49,7 +50,7 @@ export const load: PageServerLoad = async ({ params, url, locals }) => { ? await getYear1962(lang, diocese1962, year) : await getYear(lang, diocese1969, year); const entry = yearMap.get(iso); - if (!entry) throw error(404, 'Not found'); + if (!entry) await errorWithVerse(fetch, url.pathname, 404, 'Not found'); const today = new Date(); const todayIso = today.toISOString().slice(0, 10); diff --git a/src/routes/[faithLang=faithLang]/[prayers=prayersLang]/[prayer]/+page.server.ts b/src/routes/[faithLang=faithLang]/[prayers=prayersLang]/[prayer]/+page.server.ts index eda8f0d6..5d4dff23 100644 --- a/src/routes/[faithLang=faithLang]/[prayers=prayersLang]/[prayer]/+page.server.ts +++ b/src/routes/[faithLang=faithLang]/[prayers=prayersLang]/[prayer]/+page.server.ts @@ -1,12 +1,13 @@ import type { PageServerLoad, Actions } from "./$types"; import { error } from "@sveltejs/kit"; +import { errorWithVerse } from '$lib/server/errorQuote'; import { validPrayerSlugs } from '$lib/data/prayerSlugs'; const angelusSlugs = new Set(['angelus', 'regina-caeli']); export const load: PageServerLoad = async ({ params, url, locals, fetch }) => { if (!validPrayerSlugs.has(params.prayer)) { - throw error(404, 'Prayer not found'); + await errorWithVerse(fetch, url.pathname, 404, 'Prayer not found'); } const latinParam = url.searchParams.get('latin'); diff --git a/src/routes/[recipeLang=recipeLang]/+error.svelte b/src/routes/[recipeLang=recipeLang]/+error.svelte index cc557181..3049fd93 100644 --- a/src/routes/[recipeLang=recipeLang]/+error.svelte +++ b/src/routes/[recipeLang=recipeLang]/+error.svelte @@ -1,6 +1,6 @@