MST
星途 面试题库

面试题:Node.js微服务跨服务错误传播与统一处理

假设你正在开发一个由多个Node.js微服务组成的系统,其中一个微服务调用另一个微服务时可能会出现各种错误。请详细说明如何实现错误从被调用微服务向调用微服务的传播,并在调用微服务端进行统一的错误处理,确保错误信息的完整性和可追溯性。
39.1万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试
  1. 被调用微服务处理
    • 抛出合适的错误:在被调用的Node.js微服务中,当出现错误时,应抛出具有足够信息的错误对象。例如,如果是数据库查询错误,可以抛出包含错误信息、查询语句等的自定义错误。
    try {
        // 数据库查询操作
        const result = await db.query('SELECT * FROM users WHERE id =?', [userId]);
    } catch (error) {
        const customError = new Error(`Database query error: ${error.message}, Query: SELECT * FROM users WHERE id = ${userId}`);
        customError.name = 'DatabaseQueryError';
        throw customError;
    }
    
    • 使用HTTP状态码:如果使用HTTP进行微服务间通信,设置合适的HTTP状态码来表示错误类型。例如,400表示客户端错误(如参数错误),500表示服务器内部错误等。在Express框架中:
    app.get('/api/data', async (req, res) => {
        try {
            // 业务逻辑
            const data = await someService.getData();
            res.json(data);
        } catch (error) {
            if (error.name === 'ValidationError') {
                res.status(400).send(error.message);
            } else {
                res.status(500).send('Internal Server Error');
            }
        }
    });
    
  2. 调用微服务处理
    • 捕获错误:在调用微服务的代码中,使用try - catch块捕获调用其他微服务时可能抛出的错误。如果是使用fetch进行HTTP调用:
    async function callOtherMicroservice() {
        try {
            const response = await fetch('http://other - microservice/api/data');
            if (!response.ok) {
                const errorText = await response.text();
                throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
            }
            const data = await response.json();
            return data;
        } catch (error) {
            // 这里捕获到从被调用微服务传播过来的错误
            handleError(error);
        }
    }
    
    • 统一错误处理:可以创建一个统一的错误处理函数,如handleError,在这个函数中,可以记录错误日志,包括错误信息、错误发生的时间、调用栈等,以确保可追溯性。
    function handleError(error) {
        const errorInfo = {
            message: error.message,
            name: error.name,
            stack: error.stack,
            timestamp: new Date().toISOString()
        };
        console.error('Error in microservice call:', errorInfo);
        // 还可以将错误信息返回给客户端,同时确保不暴露敏感信息
        return res.status(500).send('An error occurred while processing your request');
    }
    
    • 错误包装(可选):如果需要在调用微服务端进一步处理错误,可以对捕获到的错误进行包装,添加更多上下文信息。
    catch (error) {
        const newError = new Error(`Error calling other microservice: ${error.message}`);
        newError.name = 'MicroserviceCallError';
        newError.stack = error.stack;
        handleError(newError);
    }