MST

星途 面试题库

面试题:Node.js错误处理中间件在大型项目架构中的设计与应用

假设你正在负责一个大型Node.js前端项目的架构设计,需要设计一套错误处理中间件。请描述该中间件的设计思路,包括如何捕获不同层级(路由层、业务逻辑层等)的错误,如何对错误进行分类处理并返回合适的HTTP状态码,以及如何与项目中的日志系统集成以便于错误排查。
48.7万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

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 状态码的逻辑
});