From 942149652d5d7233ef0ade1f86f8ccf78fcecdad Mon Sep 17 00:00:00 2001 From: YummYume Date: Sat, 6 Jan 2024 11:10:21 +0100 Subject: [PATCH] Add error handling --- src/app.d.ts | 7 +++- src/error.html | 17 +++++++++ src/hooks.server.ts | 28 +++++++++++++- src/lib/components/Assistant.svelte | 5 ++- src/lib/server/GPT.ts | 15 ++++++++ src/routes/+error.svelte | 42 +++++++++++++++++++++ src/routes/recipes/[slug]/+layout.server.ts | 20 ++++++++-- 7 files changed, 127 insertions(+), 7 deletions(-) create mode 100644 src/error.html create mode 100644 src/routes/+error.svelte diff --git a/src/app.d.ts b/src/app.d.ts index 0ad7aaf..1fb40f1 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -8,7 +8,12 @@ import type { AuthRequest, Session } from 'lucia'; // for information about these interfaces declare global { namespace App { - // interface Error {} + interface Error { + message: string; + carlosContext?: { + prompt: string; + }; + } interface Locals { db: PrismaClient; auth: AuthRequest; diff --git a/src/error.html b/src/error.html new file mode 100644 index 0000000..c804fc9 --- /dev/null +++ b/src/error.html @@ -0,0 +1,17 @@ + + + + + + + + + %sveltekit.status% - %sveltekit.error.message% + + + +

%sveltekit.status% - %sveltekit.error.message%

+

Quelque chose s'est très très mal passé. Nous sommes désolés pour la gêne occasionnée.

+ Retour à l'accueil + + diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 12484db..d07f6a1 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -1,7 +1,13 @@ +import { CARLOS_DEFAULT_ERROR_PROMPT, CARLOS_ERROR_PROMPT } from '$lib/server/GPT'; import { auth } from '$lib/server/auth'; import { db } from '$lib/server/db'; -import type { Handle } from '@sveltejs/kit'; +import type { Handle, HandleServerError } from '@sveltejs/kit'; + +const ERROR_MESSAGE: Record<'404' | '500' | string, string> = { + 404: "La page demandée n'existe pas.", + 500: 'Le serveur a rencontré un problème.', +}; export const handle: Handle = async ({ event, resolve }) => { event.locals.db = db; @@ -10,3 +16,23 @@ export const handle: Handle = async ({ event, resolve }) => { return resolve(event); }; + +export const handleError: HandleServerError = async ({ message, status, error }) => { + if (status >= 500) { + // eslint-disable-next-line no-console + console.log(`Unhandled error "${message}" with status ${status}:`, error); + } + + let prompt = `L'utilisateur se trouve actuellement sur une page d'erreur ${status}.`; + + if (CARLOS_ERROR_PROMPT[status.toString()]) { + prompt += CARLOS_ERROR_PROMPT[status.toString()]; + } + + prompt += CARLOS_DEFAULT_ERROR_PROMPT; + + return { + message: ERROR_MESSAGE[status.toString()] || message, + carlosContext: { prompt }, + }; +}; diff --git a/src/lib/components/Assistant.svelte b/src/lib/components/Assistant.svelte index 7bf155d..b7b28aa 100644 --- a/src/lib/components/Assistant.svelte +++ b/src/lib/components/Assistant.svelte @@ -131,7 +131,7 @@ ]; const context = { - prompt: $page.data.carlosContext?.prompt, + prompt: $page.data.carlosContext?.prompt ?? $page.error?.carlosContext?.prompt, }; abortController = new AbortController(); @@ -217,7 +217,8 @@ containerClass="border-2 border-primary-700" innerContainerClass="sm:min-h-[50vh] min-h-[55vh] flex flex-col" > - {@const carlosHasContext = $page.data.carlosContext?.prompt} + {@const carlosHasContext = + $page.data.carlosContext?.prompt ?? $page.error?.carlosContext?.prompt}
diff --git a/src/lib/server/GPT.ts b/src/lib/server/GPT.ts index 25e610c..703daec 100644 --- a/src/lib/server/GPT.ts +++ b/src/lib/server/GPT.ts @@ -2,6 +2,21 @@ import OpenAI from 'openai'; import { OPENAI_API_KEY } from '$env/static/private'; +export const CARLOS_DEFAULT_ERROR_PROMPT = ` + Ton but est d'aider l'utilisateur à résoudre son problème. + Indique à l'utilisateur qu'il peut retourner sur la page d'accueil en cliquant sur le bouton "Retour à l'accueil". +`; +export const CARLOS_ERROR_PROMPT: Record<'404' | '500' | string, string> = { + 404: ` + Si l'utilisateur te sollicite, indique lui que la page demandée n'existe pas. + Demande à l'utilisateur de vérifier l'URL ou de retourner sur la page d'accueil. + `, + 500: ` + Si l'utilisateur te sollicite, indique lui que le serveur a rencontré un problème. + Demande à l'utilisateur de réessayer plus tard ou de retourner sur la page d'accueil. + `, +}; + export const openai = new OpenAI({ apiKey: OPENAI_API_KEY, }); diff --git a/src/routes/+error.svelte b/src/routes/+error.svelte new file mode 100644 index 0000000..dad2a70 --- /dev/null +++ b/src/routes/+error.svelte @@ -0,0 +1,42 @@ + + + + {$page.status} + + + + + +
+
+
+

+ {$page.status} +

+

+ {$page.error?.message ?? 'Une erreur est survenue.'} +

+

+ Besoin d'aide ? peut vous aider. +

+ + Retour à l'accueil + +
+
+
diff --git a/src/routes/recipes/[slug]/+layout.server.ts b/src/routes/recipes/[slug]/+layout.server.ts index 1c13e67..7498f89 100644 --- a/src/routes/recipes/[slug]/+layout.server.ts +++ b/src/routes/recipes/[slug]/+layout.server.ts @@ -1,10 +1,16 @@ import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; -import { error } from '@sveltejs/kit'; +import { error, redirect } from '@sveltejs/kit'; + +import { CARLOS_DEFAULT_ERROR_PROMPT } from '$lib/server/GPT'; import type { LayoutServerLoad } from './$types'; -export const load = (async ({ params, locals }) => { - const { db } = locals; +export const load = (async ({ locals, params }) => { + const { db, session } = locals; + + if (!session) { + redirect(303, '/login'); + } try { const recipe = await db.recipe.findUniqueOrThrow({ @@ -21,6 +27,14 @@ export const load = (async ({ params, locals }) => { if (e.code === 'P2025') { error(404, { message: "Cette recette n'existe pas.", + carlosContext: { + prompt: ` + L'utilisateur se trouve actuellement sur une page d'erreur 404. + Si l'utilisateur te sollicite, indique lui que la recette demandée n'existe pas. + Demande à l'utilisateur de vérifier l'URL ou de retourner sur la page d'accueil. + ${CARLOS_DEFAULT_ERROR_PROMPT} + `, + }, }); } }