-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unify handling of error responses in page endpoints #5633
Comments
Some open questions I just thought of: Would we want to continue to merge the How do we want to deal with competing Is calling the GET handler as part of a non-GET request too much magic after all? Is there a more explicit way to deal with this, where we can avoid the above questions, but which isn't a huge hassle to use? |
I think it would be nice to have case of rendering regular page or error page. such as:
for ALL METHODs( |
I'm pretty confused about how to handle the many potential errors which have appropriate HTTP status codes other than 500. It would help if GET and other requests were consistent at least. However I'm not sure that gets to the root of the problem. I'm not sure I grasp the current situation, so I'll say what I am doing now. Currently I throw my own exception types with HTTP status code attached. // $lib/error.ts
export class Http extends Error {
status: number = 500;
constructor(message: string, status?: number) {
super(message);
if (status)
this.status = status;
}
}
// In /blogs/[user]
import error from '$lib/error';
export const GET: RequestHandler = error.wrap(async (ev) => {
const { params } = ev;
const user_id = await db.get('user', params.user);
if (!user_id)
throw new error.Http(`Could not find user nickname: ${params.user}`, 404);
... The above tries to get a page like Anyway, note the export class Span extends Http {
span: string;
constructor(message: string, status: number, span: string) {
super(message, status);
this.span = span;
}
}
export function to_resp(event: RequestEvent, error: Http | Error):
RequestHandlerOutput<ResponseBody>
{
let resp;
if (error instanceof Http) {
resp = {
status: error.status,
body: new Span(error.message, error.status, event.locals.span.id)
};
} else {
resp = {
status: 500,
body: new Span(error.message, 500, event.locals.span.id)
};
}
return resp;
}
interface AsyncRequestHandler<
P extends Record<string, string> = Record<string, string>
> extends RequestHandler<P, ResponseBody> {
(event: RequestEvent<P>): Promise<RequestHandlerOutput<ResponseBody>>;
}
export function wrap<
P extends Record<string, string>
> (fn: AsyncRequestHandler<P>): AsyncRequestHandler<P>
{
return async (event) => {
return fn(event).catch((error) => {
return to_resp(event, error);
});
};
} This catches any exceptions (or a promise rejection for some other reason), then augments the Error object with a 'span' ID so that it can be displayed to the end user to help with technical support. Because SvelteKit discards any props I have to put it in the error. That's OK I suppose (well maybe not), the problem is being forced to wrap the endpoints in this way. I'm not sure if that is necessary, but the Changing the Setting the body to an error object might also not be the best idea. As the error object gets serialised and sent to the client. The stack is removed, but that's not necessarily the only sensitive information. Perhaps, when there is an uncaught error (or error is set on |
With the API rework this behavior has changed: Page endpoints (now
Standalone endpoints (now
Therefore I think the things in here are outdated, and the new behavior is consistent, so I'm closing this. |
Describe the problem
The handling of error responses from page endpoints is currently a bit confusing and unflexible.
If a GET page endpoint returns a 4xx or 5xx response, then any props returned in its
body
are ignored and the nearest__error.svelte
page is rendered. Ifbody
is anError
instance, then this (along with its enumerable properties) are available to that page.If a non-GET page endpoint returns a 4xx or 5xx response, then any props returned in its
body
argument are passed to the regular (non-error) page, merged with the GET page endpointbody
props, if any. Ifbody
is anError
instance, then (I believe) the nearest__error.svelte
page is rendered instead and is sent this error.Describe the proposed solution
I think it would be nice, whether the user is on a GET or non-GET endpoint, to use the response from the
body
- whether it's a POJO or anError
- to determine whether to render the regular page or the nearest__error.svelte
page, respectively.I'm not sure what other fallout of this might be.
I'm not sure what we want to do if a page endpoint returns a 4xx/5xx
status
but nobody
at all. Create anew Error()
whose message is the appropriate description for that HTTP status code?Alternatives considered
No response
Importance
would make my life easier
Additional Information
No response
The text was updated successfully, but these errors were encountered: