MST
星途 面试题库

面试题:Node.js 中 try...catch 在复杂模块结构下对同步错误的精准捕获与处理

在一个大型 Node.js 项目中,有多个相互依赖的模块,每个模块都有各自的同步操作可能会抛出错误。现在要求你设计一个统一的 try...catch 机制,能够精准捕获每个模块中特定类型的同步错误,并根据不同模块的错误类型进行不同的处理(如某些模块错误需要重试操作,某些模块错误需要向上层调用者抛出特定格式的错误信息)。请阐述你的设计思路,并给出关键代码示例。
49.2万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 封装模块调用:对每个模块的同步操作进行封装,在封装函数中使用 try...catch 块捕获错误。
  2. 错误分类处理:根据模块来源和错误类型,进行不同的处理逻辑。可以通过在捕获错误时判断错误类型以及模块标识来决定处理方式。
  3. 重试机制:对于需要重试的模块错误,实现一个重试函数,在捕获到特定错误时调用重试函数。
  4. 错误抛出:对于需要向上层调用者抛出特定格式错误信息的模块错误,构造并抛出新的错误。

关键代码示例

假设项目结构如下,有 moduleAmoduleB 两个模块,每个模块都有一个同步函数会抛出错误。

模块 A

// moduleA.js
function syncOperationA() {
    // 模拟可能抛出错误的同步操作
    if (Math.random() > 0.5) {
        throw new Error('Module A specific error');
    }
    return 'Module A operation success';
}

module.exports = {
    syncOperationA
};

模块 B

// moduleB.js
function syncOperationB() {
    // 模拟可能抛出错误的同步操作
    if (Math.random() > 0.6) {
        throw new Error('Module B specific error');
    }
    return 'Module B operation success';
}

module.exports = {
    syncOperationB
};

统一错误处理封装

// errorHandler.js
function retryOperation(func, maxRetries = 3) {
    let retries = 0;
    while (retries < maxRetries) {
        try {
            return func();
        } catch (error) {
            retries++;
            if (retries === maxRetries) {
                throw error;
            }
        }
    }
}

function handleModuleError(moduleName, error) {
    if (moduleName === 'moduleA' && error.message.includes('Module A specific error')) {
        try {
            return retryOperation(() => require('./moduleA').syncOperationA());
        } catch (retryError) {
            throw new Error(`Retry failed for module A: ${retryError.message}`);
        }
    } else if (moduleName === 'moduleB' && error.message.includes('Module B specific error')) {
        throw new Error(`Module B error: ${error.message}`);
    } else {
        throw error;
    }
}

function wrapper(moduleName, operation) {
    try {
        return operation();
    } catch (error) {
        return handleModuleError(moduleName, error);
    }
}

module.exports = {
    wrapper
};

使用示例

// main.js
const { wrapper } = require('./errorHandler');

const resultA = wrapper('moduleA', () => require('./moduleA').syncOperationA());
console.log(resultA);

const resultB = wrapper('moduleB', () => require('./moduleB').syncOperationB());
console.log(resultB);

在上述代码中:

  1. retryOperation 函数实现了重试逻辑,最多重试 maxRetries 次。
  2. handleModuleError 函数根据模块名和错误信息判断错误类型,并进行不同处理。模块 A 的特定错误进行重试,模块 B 的特定错误构造新的错误抛出。
  3. wrapper 函数封装了模块操作,捕获错误并交给 handleModuleError 处理。
  4. main.js 中,通过 wrapper 调用模块的同步操作,实现统一的错误处理。