diff --git a/apps/web/src/routes/+error.svelte b/apps/web/src/routes/+error.svelte new file mode 100644 index 00000000..d7118f8d --- /dev/null +++ b/apps/web/src/routes/+error.svelte @@ -0,0 +1,137 @@ + + + + Error | DevCard + + +
+
+
+ + + + + +
+ +

Oops! Something went wrong

+ +

+ We encountered an unexpected error while loading this developer card. +
+ {#if $page.error?.message} + {$page.status}: {$page.error.message} + {/if} +

+ +
+ + + Go Home + +
+
+
+ + diff --git a/apps/web/src/routes/devcard/[id]/+page.server.ts b/apps/web/src/routes/devcard/[id]/+page.server.ts index a93fbc75..00e9a2db 100644 --- a/apps/web/src/routes/devcard/[id]/+page.server.ts +++ b/apps/web/src/routes/devcard/[id]/+page.server.ts @@ -1,4 +1,4 @@ -import { error } from '@sveltejs/kit'; +import { error, isHttpError } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; const API_BASE = process.env.BACKEND_URL || 'http://localhost:3000'; @@ -19,10 +19,13 @@ export const load: PageServerLoad = async ({ params, fetch }) => { const card = await res.json(); return { card }; - } catch (error) { - if (error && typeof error === 'object' && 'status' in error) { - throw error; + } catch (err: unknown) { + // Type guard for SvelteKit error objects + if (isHttpError(err)) { + throw err; } - throw error(500, 'Failed to connect to backend'); + // Use a different variable name to avoid collision with imported 'error' function + const httpError = error(500, 'Failed to connect to backend'); + throw httpError; } }; diff --git a/apps/web/src/routes/devcard/[id]/image.png b/apps/web/src/routes/devcard/[id]/image.png new file mode 100644 index 00000000..91a6e107 Binary files /dev/null and b/apps/web/src/routes/devcard/[id]/image.png differ diff --git a/apps/web/src/routes/u/[username]/+page.svelte b/apps/web/src/routes/u/[username]/+page.svelte index 50cb4226..f941c70e 100644 --- a/apps/web/src/routes/u/[username]/+page.svelte +++ b/apps/web/src/routes/u/[username]/+page.svelte @@ -3,8 +3,8 @@ import { onMount } from 'svelte'; let { data } = $props(); - const profile = data.profile; - const error = data.error; + const profile = $derived(data?.profile); + const error = $derived(data?.error); const platformColors: Record = { github: '#181717', linkedin: '#0A66C2', twitter: '#000000', @@ -17,7 +17,8 @@ let mounted = $state(false); let copyMessage = $state(''); let copyStatus = $state<'success' | 'error'>('success'); - let copyMessageTimeout: ReturnType; + let copyMessageTimeout: ReturnType | undefined = undefined; + let copyTimeout: ReturnType | undefined = undefined; onMount(() => { mounted = true; @@ -37,7 +38,9 @@ clearTimeout(copyMessageTimeout); } - clearTimeout(copyTimeout); + if (copyTimeout) { + clearTimeout(copyTimeout); + } copyTimeout = setTimeout(() => { copyMessage = '';