Replies: 6 comments 1 reply
-
Me too having this problem. @aphilas Did you come to any solution? |
Beta Was this translation helpful? Give feedback.
-
I have the same problems, plus a general dislike of the quirky "throw success (sometimes,) return errors (sometimes)" semantic that the My own wrapper is a WIP and too messy to show, but it's basically this... import {
invalid,
redirect,
error as skExpectedError,
type Action,
type RequestEvent
} from '@sveltejs/kit';
export const wrapAction =(
wrapped: <T extends Record<string, unknown>>(event: RequestEvent) => Promise<T>
): Action => {
const skAction = async (event: RequestEvent) => {
try {
const result = await wrapped(event);
// In my case I'd like to be able to return as well as throw a redirect. So...
if (result instanceof MyRedirect) {
// this throw is handled in the catch, below
throw result;
}
return result;
} catch (error) {
if (error instanceof MyFormValidationError) {
return invalid(error.status, {
formData: error.formData,
formErrors: error.formErrors
});
}
if (error instanceof MyRedirect) {
throw redirect(error.status, error.location);
}
if (error instanceof MyExpectedError) {
throw skExpectedError(error.status, error.message);
}
// unexpected error...
throw error;
}
};
return skAction;
}; This allows me to // src/routes/sign-in/+page.server.ts
export const _unwrappedSignIn = async (event: RequestEvent) => {
// A helper. It throws MyFormValidationError
const data = validateForm(
await event.request.formData(),
signInFormDefinition
);
const { email, password, remember } = data;
const db = getPrismaClientInstance();
const userAccount = await db.userAccount.findUnique({ where: { email } });
if (!userAccount) {
throw new MyFormValidationError<SignInFormData>(data, {
email: `We could not find an account with the email "${email}."`
});
}
if (!(await comparePassword(password, userAccount.password))) {
throw new MyFormValidationError<SignInFormData>(data, {
password: `Wrong password.`
});
}
const { authRedirect, user } = await login(
event,
userAccount.userId,
remember
);
const message = `Welcome, ${user.profile?.name}. You’re signed in.`;
if (isFetchRequest(event)) {
return { authRedirect, message };
}
setFlashMessage(event, message);
return new MyRedirect(authRedirect);
};
export const actions: Actions = {
default: wrapAction(_unwrappedSignIn)
}; |
Beta Was this translation helpful? Give feedback.
-
For the first one, just change the name of the catch argument: try {
const result = await db.insert()
} catch (e) { // <-- change this
// Handle different errors here
throw error(400, 'Could not add ice cream') // Oops: error is not callable
} For the second one: let result
try {
result = await db.insert()
} catch (e) {
throw error(400, e?.message ?? 'Something went wrong')
}
if (!result) throw redirect(303, '/') Also, maybe have a look at neverthrow to wrap you code so you don't need try/catch. |
Beta Was this translation helpful? Give feedback.
-
"throwing a redirect() inside the try block." |
Beta Was this translation helpful? Give feedback.
-
Scope is everything. As @danawoodman shows, the name you are using ( try {
result = await db.insert()
} catch (reason) {
throw error(400, reason?.message ?? 'Something went wrong')
} As for throwing inside a try {
const result = await db.insert()
if (result) {
// process and return the result
}
} catch (reason) {
throw error(400, reason?.message ?? 'Something went wrong')
}
throw redirect(303, '/') // nothing went wrong, but we didn't get a result |
Beta Was this translation helpful? Give feedback.
-
I faced a similar issue: redirecting based on the result of an const result = await db.insert()
.then(result => result.someKey)
.catch(console.error);
redirect(303, result); |
Beta Was this translation helpful? Give feedback.
-
With the new changes I've been bitten a few times over what seems like minutiae.
An
error
parameter in thetry-catch
block shadowing the sveltekiterror()
method.With the default VSCode snippets, the exception object is called
error
which shadows theerror
method, especially inload()
endpoints in+page.server.ts
.One solution is editing the snippets to name the exception object
err
or whatever else you fancy.throw
ing aredirect()
inside thetry
block.After hours of rapping at the keyboard, what seems obvious took me a minute to figure out. In a
POST
page action, I was intending to redirect based on some logic. Theredirect
error gets caught into thecatch
block.One solution could be
throw
ing outside thetry...catch
block, say after successfully creating a new resource, or throwing a new error and then performing the redirect in thecatch
block.The above gotchas are not particularly footguns of SvelteKit, just the end product of how I structured my code. Thought I'd share in case a Kit newbie (like me) bumps into the same.
Beta Was this translation helpful? Give feedback.
All reactions