Skip to content

Have error helper redirect to error page when thrown in handle hook for an underlying load request #7272

@theetrain

Description

@theetrain

Describe the problem

Similar to #6738

The documentation for +error.svelte and Loading data > errors is clear in covering behaviours of the error helper function in that it directs users to the nearest +error.svelte page when thrown in any load method, or returns an error Response object when thrown in an endpoint.

Through trial and error, I learned when an error is thrown in handle it returns an error response no matter if the request if for a load or endpoint or something else. For pages, this leads to a generic 500-error page.

Demonstration: https://stackblitz.com/edit/sveltekit-handle-error?file=README.md,src%2Fhooks.server.js&terminal=dev

My specific context is I have a src/routes/[branch]/+layout.svelte file whose handle method connects to a database based on the branch param. If I cannot connect to the database with this branch value, the DB connection throws an error, and I want that to translate to a 404 error in SvelteKit.

Describe the proposed solution

Have the behaviour of throw error() correspond to the request's context when called in handle. This would mean:

  1. When the request is a page load, then throw error() routes to the nearest +error.svelte with an error message when thrown in handle.
  2. When the request is an endpoint, then throw error() returns its error message to the requester when thrown in handle.

Alternatives considered

This isn't an earnest ask since I already have a decent workaround as suggested here: #6738 (comment).

Given the file structure src/routes/[branch]/someotherpage:

  1. Add a src/routes/+error.svelte page to catch and display errors thrown in src/routes/[branch] or deeper.

  2. Pass an error message to event.locals in the handle hook:

    import { error } from '@sveltejs/kit';
    
    export async function handle({ event, resolve }) {
      try {
        event.locals.db = await dbConnect(branch)
      } catch (err) {
        // add error to be later thrown in the layout `load` 
        event.locals.error = [404, `Branch "${branch}" does not exist.`]
        const response = await resolve(event)
        return response
      }
    }
  3. Handle error in src/routes/[branch]/+layout.server.js

    import { error } from '@sveltejs/kit'
    
    /** @type {import('./$types').LayoutServerLoad} */
    export async function load ({ locals }) {
      if (locals.error?.length > 0) {
        // this uses the spread operator since `locals.error`
        // is an array of parameters
        throw error(...locals.error)
      }
      // ...
    }

Demonstration of workaround: https://stackblitz.com/edit/sveltekit-handle-error-workaround?file=src%2Fhooks.server.js,src%2Froutes%2F[branch]%2F%2Bpage.server.js&terminal=dev

Importance

nice to have

Additional Information

More personal context for posterity not directly related to this issue: #6788 (comment)

If this proposal sounds favourable, then great. If it's something that won't be implemented, then I'd like to at least help clarify the behaviour of error somewhere in the docs when it comes to being thrown in handle, load, or a server endpoint. Along with documentation, I hope the alternative explained above can help others in the future.

As always, thank you SvelteKit maintainers for your time and efforts!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions