`+error.svelte` needs to have a `load` function
See original GitHub issueDescribe the problem
Previously error pages could have load
functions, just like regular pages, from #5748 onwards that’s no longer possible, the rationale given was that an error page doesn’t really need a load function and a load function could potentially screw things up further.
But I think a very important and common scenario was overlooked: You might want to return data from the error page’s load function that the layout will then consume, and just things of that nature in general. So for instance:
error.ts
:
export const load: ErrorLoad = () => {
return {
meta: {
title: "404 Not Found",
showFooter: false
}
};
};
This is actually very serious. I just realized there’s no way of doing this right now, but it’s needed in a lot of cases obviously. The current design doesn’t provide any alternative.
Describe the proposed solution
Just allow error pages to have load
functions like before please. You could then just simply point out in the docs that the load function of an error page must avoid doing anything that could potentially result in another error.
Alternatives considered
No response
Importance
i cannot use SvelteKit without it
Additional Information
No response
Issue Analytics
- State:
- Created a year ago
- Reactions:8
- Comments:16 (11 by maintainers)
The
+layout.svelte
example you gave is exactly what I had in mind. I just don’t agree that it’s a big problem — this……seems preferable to having to have this for every single error boundary:
It strikes me as unlikely that you’d often need to vary the messages on a per-error-boundary rather than on a per-status or per-error basis, in which case having the logic centralised in the layout is better. But if you really do need to vary it based on the route, you have access to
$page.params
and$page.routeId
.I’d argue that the current approach makes common approaches easy and less-common approaches possible. What you’re arguing for makes the less-common approaches slightly easier, but at the cost of a more complex mental model.
Well, I’d write the
<title>
like this for one thing — I wouldn’t have two ternaries when one will do:(I’m also not sure where
titleSuffixes.short
is expressed in the alternative code.)Is the first example preferable to the second? No. Is it preferable to the second if you have multiple error boundaries? Yes, absolutely. The code in the first example isn’t going to make anyone swoon, but it’s fine, and if it really starts to get convoluted then you can just do
<title>{getTitle($page)}</title>
.I’m not trying to be awkward here. The ability to run an asynchronous
load
function when trying to handle errors is a genuine source of complexity. If something goes wrong during thatload
(which is likely! If the conditions were right for an error to occur in the layout/pageload
functions, such as the user being offline, then there’s a better-than-normal chance that they’re right for the errorload
to fail as well), then we have to start making decisions: do we try and walk our way back up the layout tree, trying parent error boundaries? (Depending on what thoseload
functions do, we could be waiting a while before we’re able to actually render something!) Which error do we use — the original error, or the error that was thrown from the errorload
? Do we bail altogether at that point and just display the root error page? What if we hit an error while running thatload
?There’s no objectively right answer to any of those questions, but because we’ve created room for that ambiguity, and make the mental model that much harder to grasp, we have to document all this behaviour, and app developers need to read that documentation and organise their
load
functions around it. And that’s before people start doingthrow redirect(...)
, creating even more opportunity for cascading failures.Successfully handling error states requires the elimination of ambiguity.
(It’s not enough to say ‘you can’t
fetch
stuff in an errorload
function’ — you need to enforce it, and that means complicating the API. Nor can you ban people fromthrow error
orthrow redirect
in an errorload
function — what are you going to do, throw a different error to tell them not to throw errors?)Against all that, ‘I don’t want to write a ternary in my
<title>
’ just isn’t a persuasive argument unfortunately.I think @harrylaulau’s proposal is intriguing. It allows data to be returned without any of the footguns that come with an error
load
function. We’d miss out on some type safety — assuming we move forward with theApp.PageData
proposal in #5951, the third argument would have to bePartial<App.PageData> & Record<string, any>
rather thanApp.PageData & Record<string, any>
because we wouldn’t have the contextual knowledge of which fields had already been supplied by parent layouts — but only a bit. It feels weird to include that sort of data when throwing an error, but not outrageously so.