设计思路
- 错误捕获:在各个模块的关键代码处,使用
try - catch
块来捕获可能出现的错误。同时,利用Node.js的全局错误事件,如process.on('uncaughtException')
和process.on('unhandledRejection')
来捕获未被处理的异常。
- 错误分类:定义不同的错误类,继承自内置的
Error
类,以便根据错误类型进行分类处理。
- 日志记录:使用日志库(如
winston
)记录错误信息,包括错误类型、错误信息、堆栈跟踪等,方便调试和排查问题。
- 向上层模块传递:在捕获到错误后,如果当前模块无法处理,将错误抛出,让上层调用模块进行处理。
关键代码示例
- 定义错误类
class CustomError extends Error {
constructor(message) {
super(message);
this.name = 'CustomError';
}
}
class DatabaseError extends CustomError {
constructor(message) {
super(message);
this.name = 'DatabaseError';
}
}
class NetworkError extends CustomError {
constructor(message) {
super(message);
this.name = 'NetworkError';
}
}
- 错误捕获与处理
const winston = require('winston');
// 配置日志记录
const logger = winston.createLogger({
level: 'error',
format: winston.format.json(),
transports: [
new winston.transport.Console()
]
});
function someFunction() {
try {
// 模拟可能抛出错误的代码
throw new DatabaseError('数据库连接失败');
} catch (error) {
if (error instanceof CustomError) {
// 记录错误日志
logger.error({
errorType: error.name,
message: error.message,
stack: error.stack
});
// 向上层模块传递错误
throw error;
} else {
// 处理其他类型的错误
logger.error({
errorType: 'UnknownError',
message: error.message,
stack: error.stack
});
throw new CustomError('未知错误');
}
}
}
// 全局捕获未处理的异常
process.on('uncaughtException', (error) => {
logger.error({
errorType: 'UncaughtException',
message: error.message,
stack: error.stack
});
console.log('未捕获的异常,应用即将退出');
process.exit(1);
});
// 全局捕获未处理的Promise拒绝
process.on('unhandledRejection', (reason, promise) => {
logger.error({
errorType: 'UnhandledRejection',
message: reason.message,
stack: reason.stack
});
console.log('未处理的Promise拒绝:', promise, reason);
});
try {
someFunction();
} catch (error) {
console.log('上层模块捕获到错误:', error.message);
}