kit
kit copied to clipboard
Make `handleError` `async`
Describe the problem
I want to use the handleError hook of SvelteKit, but I realized that it currently has to be a synchronous function. But unfortunately, our error mapper is an asynchronous function. Since it is not possible in JavaScript to synchronously await an asynchronous function (like in C#), it seems we cannot use the handleError hook currently.
Describe the proposed solution
Make the return type of HandleServerError and HandleClientError a MaybePromise, like the handle-hook.
export interface HandleServerError {
(input: { error: unknown; event: RequestEvent }): MaybePromise<void | App.Error>;
}
export interface HandleClientError {
(input: { error: unknown; event: NavigationEvent }): MaybePromise<void | App.Error>;
}
Alternatives considered
Continue not to use handleError.
Importance
would make my life easier
Additional Information
No response
What is your error mapper doing that needs it to be asynchronous?
Some of the error objects are Response objects (these come from a third-party library, so we cannot change this behavior). In our error mapper, we need to read the content of the response with await response.json(), because it contains an error dto we need for proper error handling and logging.
How important is it that the DTO is attached to the publicly-facing error? In other words, could you do this?
export function handleError({ error, event }) {
getLoggingData(error).then(data => {
console.log(data);
});
return {
message: 'oh no'
};
}
Making handleError async makes me somewhat nervous — if something goes wrong, we ideally need the simplest/fastest possible path to recovery. Adding async moving parts complicates that — for example what if the third-party service is temporarily unavailable? By enforcing a sync signature, that async work can happen in the background where failure is non-catastrophic.
I feel the same honestly, but did the PR regardless, mainly to see how much impact on the code base it has. It's something of a "if you want to shoot yourself in the foot real bad you can do so anyway" situation, with async making this a little easier.
Unfortunately, we have to read the DTO. Our server-side SvelteKit code is more or less just a pass-through layer to other backend microservices. Therefore we need the DTO to show meaningful messages to the user. We need to show the user as well as possible what the problem is and a possible solution for the problem. We work in a business environment where it is not accepted if we always just show general errors. We have to show specific errors everywhere, where we know the reason for the error and the next step the user should do.
If you say that you cannot or do not want to implement an async handleError, then we have to continue using our current error-handling approach, a big try-catch in any load function.
I can sympathize with such situations, because I've been in these previously, too. It's not great to have to do this, but if people have to, we shouldn't be in the business of actively prohibiting it, which in your case leads to more repetitive code which only moves the issue of having to do a backend call elsewhere.