在express的错误处理,使用以下代码
import { Request, Response, NextFunction } from 'express';
import createError from 'http-errors';
// ...
app.use((req: Request, res: Response, next: NextFunction) => {
next(new createError.NotFound());
});
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
res.status(err.status || 500);
res.send({
error: {
status: err.status || 500,
message: err.message,
}
});
})
// ...
其中,在第二个 use
中,回调函数第一个参数为 err
,此时参数个数为 4 个。
但是,一般的回调函数包含 3 个参数,req, res, next
,观察到,err
应该是可选参数,是个异常错误对象。
注意
如果需要使用 err
参数,需要完整地把 4 个参数都写出来,即按顺序 err, req, res, next
,不管你后面的参数是否有使用,都要写上去,才能正常访问 err
变量。
一个猜测
一个猜想,不一定对,express内部会根据你传递参数的个数,进行判断,为形参赋值,供函数内部调用。
export type RequestHandlerParams<
P = ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = ParsedQs,
Locals extends Record<string, any> = Record<string, any>
> =
| RequestHandler<P, ResBody, ReqBody, ReqQuery, Locals>
| ErrorRequestHandler<P, ResBody, ReqBody, ReqQuery, Locals>
| Array<RequestHandler<P> | ErrorRequestHandler<P>>;
export interface RequestHandler<
P = ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = ParsedQs,
Locals extends Record<string, any> = Record<string, any>
> {
(
req: Request<P, ResBody, ReqBody, ReqQuery, Locals>,
res: Response<ResBody, Locals>,
next: NextFunction,
): void;
export type ErrorRequestHandler<
P = ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = ParsedQs,
Locals extends Record<string, any> = Record<string, any>
> = (
err: any,
req: Request<P, ResBody, ReqBody, ReqQuery, Locals>,
res: Response<ResBody, Locals>,
next: NextFunction,
) => void;
从源码层面可以看到,确实是分别是 RequestHandler
和 ErrorRequestHandler
两种类型。
但是查看express源码未能找到这部分逻辑,功力不够o(╥﹏╥)o。