1. 捕获不同层级错误
- 路由层:利用 Express 等框架提供的错误处理机制,在路由定义时,通过
next
函数将错误传递到全局错误处理中间件。例如在 Express 中,在路由处理函数内如果发生错误,可以这样处理:
app.get('/example', (req, res, next) => {
try {
// 业务逻辑
throw new Error('路由层错误');
} catch (error) {
next(error);
}
});
- 业务逻辑层:在业务逻辑模块中,使用
try - catch
块捕获可能出现的错误,并将其包装成合适的格式再抛出,以便上层捕获处理。例如:
function businessLogic() {
try {
// 复杂业务逻辑
throw new Error('业务逻辑层错误');
} catch (error) {
throw new CustomError('业务逻辑层错误', error);
}
}
2. 错误分类处理与返回 HTTP 状态码
- 定义错误类型:创建不同的错误类,继承自内置的
Error
类,用于区分不同类型的错误。例如:
class BadRequestError extends Error {
constructor(message) {
super(message);
this.name = 'BadRequestError';
this.statusCode = 400;
}
}
class InternalServerError extends Error {
constructor(message) {
super(message);
this.name = 'InternalServerError';
this.statusCode = 500;
}
}
- 全局错误处理中间件:在全局错误处理中间件中,根据错误类型返回相应的 HTTP 状态码。例如在 Express 中:
app.use((error, req, res, next) => {
if (error instanceof BadRequestError) {
res.status(error.statusCode).json({ error: error.message });
} else if (error instanceof InternalServerError) {
res.status(error.statusCode).json({ error: '服务器内部错误' });
} else {
res.status(500).json({ error: '未知错误' });
}
});
3. 与日志系统集成
- 选择日志库:例如使用
winston
作为日志库。安装winston
后进行如下配置:
const winston = require('winston');
const logger = winston.createLogger({
level: 'error',
format: winston.format.json(),
transports: [
new winston.transport.Console(),
new winston.transport.File({ filename: 'error.log' })
]
});
- 在错误处理中记录日志:在全局错误处理中间件中,使用日志库记录错误信息。例如:
app.use((error, req, res, next) => {
logger.error({
message: error.message,
stack: error.stack,
statusCode: error.statusCode || 500,
requestUrl: req.url
});
// 错误分类处理并返回 HTTP 状态码的逻辑
});