Skip to content

Ease error handling in SvelteKit with functions to help with catching, parsing and logging errors

License

Notifications You must be signed in to change notification settings

feelinglovelynow/svelte-catch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ•‰ @feelinglovelynow/svelte-catch

πŸ’Ž Install

pnpm add @feelinglovelynow/svelte-catch

πŸ™ Description

  • Ease error handling in SvelteKit with functions to help with catching, parsing and logging errors
  • Errors condense down to an array of strings that works nicely with @feelinglovelynow/toast
  • Original error, formatted error, and stack trace is logged on error

πŸ’š Add log and trace to terminal

  • log (data: any): void
import { log } from '@feelinglovelynow/svelte-catch'

log({ hello: 'world', foo: 'bar' })
  • Terminal Output
---FLN LOG START---
{ hello: 'world', foo: 'bar' }
Trace
    at Module.log (/Users/fln/@feelinglovelynow/svelte-catch/dist/log.js:6:13)
    at load (/Users/fln/feelinglovelynow/src/routes/+layout.server.ts:18:27)
    at Module.load_server_data (/Users/fln/feelinglovelynow/node_modules/.pnpm/@sveltejs+kit@1.27.6_svelte@4.2.3_vite@4.5.0/node_modules/@sveltejs/kit/src/runtime/server/page/load_data.js:57:41)
---FLN LOG END---

πŸ’› Add these helper functions to ease working with @feelinglovelynow/svelte-catch

import { onMount } from 'svelte'
import { json } from '@sveltejs/kit'
import showToast from '@feelinglovelynow/toast'
import { SvelteCatch, enumCatchLocation } from '@feelinglovelynow/svelte-catch'


export function pageServerCatch (e: any) {
  const svelteCatch = new SvelteCatch(enumCatchLocation.pageServer, 'We apologize, there is an error with this page. Please try again and/or <a href="/links">contact us</a>')
  return svelteCatch.catch(e)
}


export function serverCatch (e: any) {
  const svelteCatch = new SvelteCatch(enumCatchLocation.server, 'We apologize, there is an error with this request. Please try again and/or <a href="/links">contact us</a>')
  return svelteCatch.catch(e, json)
}


export function routeCatch (data: any) {
  if (data?._errors?.length) {
    onMount(() => {
      showToast('info', data._errors)
    })
  }
}

🧑 Throw one error

import { one } from '@feelinglovelynow/svelte-catch'

export const load = (async () => {
  try {
    throw one('hello world', { foo: 'bar' })
  } catch (e) {
    return pageServerCatch(e)
  }
}) satisfies LayoutServerLoad
  • Terminal Output
  • originalError is the error that was recieved by the format error function
  • formattedError is the error that will be returned to the frontend
---FLN LOG START---
{
  originalError: { _errors: [ 'hello world' ], _errorData: { foo: 'bar' } },
  formattedError: { _errors: [ 'hello world' ] }
}
Trace
    at Module.log (/Users/fln/@feelinglovelynow/svelte-catch/dist/log.js:6:13)
    at SvelteCatch.catch (/Users/fln/@feelinglovelynow/svelte-catch/dist/SvelteCatch.js:18:35)
    at Module.pageServerCatch (/Users/fln/feelinglovelynow/src/lib/global/catch.ts:11:27)
---FLN LOG END---
  • Frontend that shows toast notification with the error
<script lang="ts">
  import type { PageData } from './$types'
  import { routeCatch } from '$lib/global/catch'

  export let data: PageData
  routeCatch(data)
</script>

❀️ Throw many errors

  • many (_errors: string[], _errorData: any = undefined)
import { many } from '@feelinglovelynow/svelte-catch'
import { serverCatch } from '$lib/global/catch'


export const GET = (async () => {
  try {
    const errors = [{ message: 'foo' }, { message: 'bar' }] // example graphql error
    const errorsAsArrayOfStrings = errors.map(e => e.message)
    const errorData = JSON.stringify({ errors })

    throw many(errorsAsArrayOfStrings, errorData)
  } catch (e) {
    return serverCatch(e)
  }
}) satisfies RequestHandler
  • Terminal Output
  • originalError is the error that was recieved by the parser
  • formattedError is the error that will be returned to the frontend
---FLN LOG START---
{
  originalError: {
    _errors: [ 'foo', 'bar' ],
    _errorData: '{"errors":[{"message":"foo"},{"message":"bar"}]}'
  },
  formattedError: { _errors: [ 'foo', 'bar' ] }
}
Trace
    at Module.log (/Users/fln/@feelinglovelynow/svelte-catch/dist/log.js:6:13)
    at SvelteCatch.catch (/Users/fln/@feelinglovelynow/svelte-catch/dist/SvelteCatch.js:19:62)
    at Module.serverCatch (/Users/fln/feelinglovelynow/src/lib/global/catch.ts:16:27)
---FLN LOG END---
  • Frontend that shows toast notification with the error
<script lang="ts">
  import type { PageData } from './$types'
  import { routeCatch } from '$lib/global/catch'

  export let data: PageData
  routeCatch(data)
</script>

πŸ’Ÿ Zod Support

  • Schema
import { z } from 'zod'


export const schemaSearch = z
  .object({
    isQuotesChecked: z.any().optional(), // allow .superRefine() to do the validation
    isSourcesByTitleChecked: z.any().optional(), // allow .superRefine() to do the validation
    isSourcesByDescriptionChecked: z.any().optional(), // allow .superRefine() to do the validation
    query: z.string().min(3, 'Query is at least 3 characters please'),
  })
  .superRefine(({ isQuotesChecked, isSourcesByTitleChecked, isSourcesByDescriptionChecked }, ctx) => {
    if (!isQuotesChecked && !isSourcesByTitleChecked && !isSourcesByDescriptionChecked) ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Select atleast one checkbox please' })
  })


export type SchemaSearch = z.infer<typeof schemaSearch>
  • Server
import type { RequestHandler } from './$types'
import { serverCatch } from '$lib/global/catch'
import { schemaSearch, type SchemaSearch } from '$lib/zod/search'


export const POST = (async ({ request }) => {
  try {
    const body = (await request.json()) as SchemaSearch
    schemaSearch.parse(body)
  } catch (e) {
    return serverCatch(e)
  }
}) satisfies RequestHandler
{
  "_errors":[
    "Select atleast one checkbox please"
  ],
  "query":{
    "_errors":[
      "Query is at least 3 characters please"
    ]
  }
}

🌟 Redirect

import { redirect } from '@sveltejs/kit'
import type { PageServerLoad } from './$types'
import { pageServerCatch } from '$lib/global/catch'

export const load = (async ({ locals }) => {
  try {
    if (!locals.userUid) throw redirect(302, '/auth/sign-in')
  } catch (e) {
    return pageServerCatch(e)
  }
}) satisfies PageServerLoad

✨ Formatted error of random error formats

  • formattedError is the error that will be returned to the frontend
  • IF _errorData is in the throw we do not return _errorData to the frontend but _errorData is logged in the terminal
throw 'hello world' // IF e is strng => we put string into array
formattedError: { _errors: [ 'hello world' ] }


throw new Error('foo') // IF e.message found => we put e.message into array
formattedError: { _errors: [ 'foo' ] }


throw { format: () => ({ foo: 'bar' }) } // IF e.format() found => formattedError is the response from e.format()
formattedError: { foo: 'bar' }


throw null // IF !e => formattedError is the default error set above @ pageServerCatch or serverCatch
formattedError: {
  _errors: [
    'We apologize, there is an error with this page. Please try again and/or <a href="/links">contact us</a>'
  ]
}


throw { _errors: [ 'hello', 'world' ], foo: 'bar' } // IF _errors array found => no parsing done
formattedError: { _errors: [ 'hello', 'world' ], foo: 'bar' }


throw { message: 'hello world' } // IF e.message found => we put e.message into array
formattedError: { _errors: [ 'hello world' ] }

🎁 All Our Packages

  1. @feelinglovelynow/dgraph: NPM β‹… Github
  2. @feelinglovelynow/env-write: NPM β‹… Github
  3. @feelinglovelynow/get-form-entries: NPM β‹… Github
  4. @feelinglovelynow/get-relative-time: NPM β‹… Github
  5. @feelinglovelynow/global-style: NPM β‹… Github
  6. @feelinglovelynow/jwt: NPM β‹… Github
  7. @feelinglovelynow/loop-backwards: NPM β‹… Github
  8. @feelinglovelynow/slug: NPM β‹… Github
  9. @feelinglovelynow/svelte-catch: NPM β‹… Github
  10. @feelinglovelynow/svelte-kv: NPM β‹… Github
  11. @feelinglovelynow/svelte-loading-anchor: NPM β‹… Github
  12. @feelinglovelynow/svelte-modal: NPM β‹… Github
  13. @feelinglovelynow/svelte-turnstile: NPM β‹… Github
  14. @feelinglovelynow/toast: NPM β‹… Github

About

Ease error handling in SvelteKit with functions to help with catching, parsing and logging errors

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published