自从在服务器离线或无法访问的极少数情况下向我的获取添加捕获处理程序以来,它永远不会返回。执行永远不会中断,终点命中。我没有从表单操作中得到任何响应,没有显示任何消息,并且永远不会命中重定向,尽管所有范围都是可访问的。
如果我在执行后重新加载,我就有了 cookie 并且可以到达 /home,它只是不会重定向或在失败时返回任何验证。
这是我的登录操作;
export const actions = {
login: async ({ cookies, request }) => {
const data = await request.formData();
const objectData = Object.fromEntries(data.entries());
const schemaCheck = schema.safeParse(objectData);
if (!schemaCheck.success) {
return { success: false, errorMessages: schemaCheck.error.errors.map((error) => {
return error.message
})}
}
await fetch(PUBLIC_API_URL + '/auth/login', {
method: "POST",
body: JSON.stringify(objectData)
})
.then(async (r) => {
const json = await r.json()
if (Object.prototype.hasOwnProperty.call(json, 'error_message')) {
return { success: false, errorMessages: [json['error_message']] };
}
cookies.set('session', json.access_token, { path: '/' });
redirect(303, '/home');
})
.catch(() => {
return { success: false, errorMessages: ['Something went wrong, try again later.']}
})
console.log('hello');
}
};
如果我删除延续和异常处理程序,它就可以正常工作。
您不应将
await
与 .then
或 .catch
混合使用。它不终止登录函数的原因是因为 return
在另一个函数作用域中。
你可以尝试这样的事情:
export const actions = {
login: async ({ cookies, request }) => {
const data = await request.formData();
const objectData = Object.fromEntries(data.entries());
const schemaCheck = schema.safeParse(objectData);
if (!schemaCheck.success) {
return {
success: false, errorMessages: schemaCheck.error.errors.map((error) => {
return error.message
})
}
}
try {
const r = await fetch(PUBLIC_API_URL + '/auth/login', {
method: "POST",
body: JSON.stringify(objectData)
});
const json = await r.json()
if (Object.prototype.hasOwnProperty.call(json, 'error_message')) {
return { success: false, errorMessages: [json['error_message']] };
}
cookies.set('session', json.access_token, { path: '/' });
redirect(303, '/home');
} catch (ex) {
return { success: false, errorMessages: ['Something went wrong, try again later.'] }
}
console.log('hello');
}
};
catch
块还捕获await fetch
中引起的错误,因此如果您的API不起作用,它也会转到catch
块。
返回值位于嵌套函数内,您需要
return await fetch(...)
才能从那里获取结果。redirect
通过抛出异常来工作,如果你再次捕获该异常,这将永远不会工作。
您可以使用第二个
then
参数来重构它,它不会捕获成功案例中抛出的错误。
return await fetch(...)
.then(
async (r) => {
// ...
redirect(...);
},
() => {
return { success: false, errorMessages: ... }
}
);
您也可以不使用链接语法,但您必须使用异常来解决
redirect
(例如捕获并重新抛出它)。