我按照express.js的教程制作了一个简单的错误处理程序
function clientErrorHandler(err, req, res, next) {
if (req.xhr) {
console.log('clienterrorhandler', err);
res.status(500).send({ error: 'Something failed!' });
} else {
next(err);
}
}
app.use(clientErrorHandler);
这就是我定义错误的方式
import { StatusCodes } from 'http-status-codes';
import CustomAPIError from './custom-errors';
class UnauthenticatedError extends CustomAPIError {
constructor(
public message: string,
public statusCode: number,
) {
super(message, statusCode);
this.statusCode = StatusCodes.UNAUTHORIZED;
}
}
export default UnauthenticatedError;
身份验证中间件
export const auth = asyncHandler(
async (
req: AuthenticatedRequest,
res: Response,
next: NextFunction,
): Promise<void> => {
try {
} catch (err) {
throw new UnauthenticatedError(
'There is no token atached to the Header.',
StatusCodes.UNAUTHORIZED,
);
}
},
);
关键问题是当错误发生时,客户端收到一个基于 html 的错误,我的错误处理程序无法正常工作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Error: Not Athorized token expired, Please Login again.<br> at authMiddleware.ts:44:15<br> at asyncUtilWrap
您依赖于 req.xhr 字段。仅当请求包含标头
X-Requested-With: XMLHttpRequest
时才设置。根据记忆,只有 jQuery 的 $.ajax()
默认设置了这个; Axios 和 fetch()
没有。
您应该通过 Accept
标头使用
内容协商,而不是使用此非标准标头(这也会导致跨域请求变得不简单)。
app.use((err, req, res, next) => {
if (req.accepts('application/json')) {
console.log('clienterrorhandler', err);
return res.status(500).json({ error: 'Something failed!' });
}
return next(err);
});
在客户端
fetch(url, {
headers: {
Accept: 'application/json',
},
});