中将 next 函数作为参数传递?"/>
是否可以在 express 中将 next 函数作为参数传递?
我正在将
NextFunction
从 express 传递到另一个函数,但我的测试 if user with given email doesn't exist
没有通过。 next
函数在此处作为参数传递给另一个函数时是否无法正常工作?
const lookupUserByEmail = async (
email: string,
next: NextFunction
): Promise<UserType | any> => {
let user: UserType | null;
try {
user = await User.findOne({ where: { email } });
if (!user) {
return next(
createError(401, {
message: 'Invalid email credentials.',
})
);
}
} catch (err) {
return next(createError(500, 'Internal server error'));
}
return user;
};
export const signin = async (
req: Request<{}, {}, SigninUserInput['body']>,
res: Response,
next: NextFunction
) => {
const { email, password } = req.body;
// check if an user with given email exists
const user: UserType = await lookupUserByEmail(email, next.bind(signin));
// check password
if (isPasswordWrong(password, user.password)) {
return next(createError(401, { message: 'Invalid credentials.' }));
}
const token = createToken(
{
id: user.id,
username: user.username,
email: user.email,
},
next
);
res
.status(200)
.json({ token: token, id: user.id, preference: user.preference });
};
回答如下:
你绝对不应该将下一个函数作为参数传递给另一个函数,因为这不是最佳实践。
你可能想在你的 index.js 文件中设置一个错误处理程序中间件,然后在你在上面的代码中调用 next() 的任何地方抛出一个错误。
您当前的 signin() 函数的更新就像这样;
export const signin = async (
req: Request<{}, {}, SigninUserInput['body']>,
res: Response,
next: NextFunction
) => {
const { email, password } = req.body;
...
// check password
if (isPasswordWrong(password, user.password)) {
throw new Error("Invalid credentials")
}
...
};
然后处理抛出的错误,你可以在你的 index.js 文件中有这样的东西;
async function errorMiddleware(
err: Error,
req: Request,
res: Response,
next: NextFunction
) {
// handle error here
}
app.use(errorMiddleware);
如果您想迎合状态代码,一种方法是抛出这样的错误;
const error = new Error("Invalid credentials.")
error.code = 401
throw error
另一种方法(更好的选择)是创建 Error 的子类,如下所示:
class CustomError extends Error {
public readonly statusCode: number;
public readonly isOperational: boolean;
constructor(
message: string,
statusCode = 500,
isOperational = true
) {
super(<string>message);
Object.setPrototypeOf(this, new.target.prototype);
this.statusCode = statusCode;
this.isOperational = isOperational;
Error.captureStackTrace(this)
}
}
因此,您抛出的错误将如下所示:
// check password
if (isPasswordWrong(password, user.password)) {
throw new CustomError(
'Invalid credentials.',
401,
);
}
要在中间件中提取错误消息和状态代码,您可以使用如下内容:
const message = err instanceof CustomError
? err.message
: 'Internal server error';
const errorCode = (<CustomError>err)?.statusCode || 500;
我希望这有帮助。
更多推荐
是否可以在 express 中将 next 函数作为参数传递?
发布评论