MST
星途 面试题库

面试题:Node.js中自定义全局错误处理器的优化与扩展

假设你已经基于`domain`模块(Node.js较老版本支持,也可基于现代方法)实现了一个全局错误处理器。现在要求对其进行优化,使其能够区分不同类型的错误(如系统错误、业务逻辑错误等),并将错误信息以不同的策略记录到日志文件中(例如,系统错误记录到`system_error.log`,业务逻辑错误记录到`business_error.log`),同时还要考虑性能和资源占用。请详细描述你的实现思路及关键代码片段。
41.7万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 错误类型定义:定义不同错误类型的类,继承自内置的Error类,以便区分不同类型的错误。
  2. 错误处理器优化:在全局错误处理器中,根据错误的类型,将其发送到不同的日志记录函数。
  3. 日志记录:使用fs模块(Node.js内置文件系统模块)将错误信息记录到相应的日志文件中。为了提高性能,考虑使用fs.createWriteStream并进行适当的缓冲处理,避免频繁的文件I/O操作。
  4. 性能与资源占用:减少不必要的文件I/O操作,采用批量写入的方式,并且在高并发场景下合理使用异步I/O操作。

关键代码片段

const fs = require('fs');
const path = require('path');

// 定义系统错误类
class SystemError extends Error {
    constructor(message) {
        super(message);
        this.name = 'SystemError';
    }
}

// 定义业务逻辑错误类
class BusinessError extends Error {
    constructor(message) {
        super(message);
        this.name = 'BusinessError';
    }
}

// 全局错误处理器
process.on('uncaughtException', (err) => {
    if (err instanceof SystemError) {
        logSystemError(err);
    } else if (err instanceof BusinessError) {
        logBusinessError(err);
    } else {
        // 其他类型错误处理
        logGeneralError(err);
    }
});

// 记录系统错误到system_error.log
function logSystemError(err) {
    const logFilePath = path.join(__dirname,'system_error.log');
    const writeStream = fs.createWriteStream(logFilePath, { flags: 'a' });
    writeStream.write(`${new Date().toISOString()} - System Error: ${err.message}\n`);
    writeStream.end();
}

// 记录业务逻辑错误到business_error.log
function logBusinessError(err) {
    const logFilePath = path.join(__dirname, 'business_error.log');
    const writeStream = fs.createWriteStream(logFilePath, { flags: 'a' });
    writeStream.write(`${new Date().toISOString()} - Business Error: ${err.message}\n`);
    writeStream.end();
}

// 记录其他类型错误到general_error.log
function logGeneralError(err) {
    const logFilePath = path.join(__dirname, 'general_error.log');
    const writeStream = fs.createWriteStream(logFilePath, { flags: 'a' });
    writeStream.write(`${new Date().toISOString()} - General Error: ${err.message}\n`);
    writeStream.end();
}

// 示例抛出系统错误
try {
    throw new SystemError('系统出现异常');
} catch (e) {
    process.emit('uncaughtException', e);
}

// 示例抛出业务逻辑错误
try {
    throw new BusinessError('业务逻辑出现问题');
} catch (e) {
    process.emit('uncaughtException', e);
}

上述代码实现了对不同类型错误的区分,并将其记录到不同的日志文件中。在实际应用中,可以根据具体需求进一步优化日志记录的方式,例如使用日志库(如winston)来提高日志管理的灵活性和性能。同时,在处理高并发场景下的错误时,需要注意文件I/O操作的性能瓶颈,可考虑使用异步和缓冲机制来优化。