119 lines
3.2 KiB
JavaScript
119 lines
3.2 KiB
JavaScript
const db = require('../../dbProxy');
|
|
|
|
/**
|
|
* 统一错误处理模块
|
|
* 负责错误分类、记录、恢复决策
|
|
*/
|
|
class ErrorHandler {
|
|
/**
|
|
* 可重试的错误类型
|
|
*/
|
|
static RETRYABLE_ERRORS = [
|
|
'ETIMEDOUT',
|
|
'ECONNRESET',
|
|
'ENOTFOUND',
|
|
'NetworkError',
|
|
'MQTT客户端未初始化',
|
|
'设备离线',
|
|
'超时'
|
|
];
|
|
|
|
/**
|
|
* 处理错误
|
|
* @param {Error} error - 错误对象
|
|
* @param {Object} context - 上下文信息
|
|
* @returns {Object} 错误处理结果
|
|
*/
|
|
static async handleError(error, context = {}) {
|
|
const errorInfo = {
|
|
message: error.message || '未知错误',
|
|
stack: error.stack || '',
|
|
code: error.code || '',
|
|
context: {
|
|
task_id: context.task_id,
|
|
sn_code: context.sn_code,
|
|
taskType: context.taskType,
|
|
...context
|
|
},
|
|
timestamp: new Date().toISOString(),
|
|
isRetryable: this.isRetryableError(error)
|
|
};
|
|
|
|
// 记录到日志
|
|
console.error(`[错误处理] ${errorInfo.message}`, {
|
|
context: errorInfo.context,
|
|
isRetryable: errorInfo.isRetryable,
|
|
stack: errorInfo.stack
|
|
});
|
|
|
|
// 错误信息已通过 console.error 记录到控制台日志
|
|
|
|
return errorInfo;
|
|
}
|
|
|
|
/**
|
|
* 判断错误是否可重试
|
|
* @param {Error} error - 错误对象
|
|
* @returns {boolean}
|
|
*/
|
|
static isRetryableError(error) {
|
|
if (!error) return false;
|
|
|
|
const errorMessage = (error.message || '').toLowerCase();
|
|
const errorCode = error.code || '';
|
|
|
|
// 检查错误代码
|
|
if (this.RETRYABLE_ERRORS.some(code => errorCode === code)) {
|
|
return true;
|
|
}
|
|
|
|
// 检查错误消息
|
|
return this.RETRYABLE_ERRORS.some(code =>
|
|
errorMessage.includes(code.toLowerCase())
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 计算重试延迟(指数退避)
|
|
* @param {number} retryCount - 当前重试次数
|
|
* @param {number} baseDelay - 基础延迟(毫秒)
|
|
* @param {number} maxDelay - 最大延迟(毫秒)
|
|
* @returns {number} 延迟时间(毫秒)
|
|
*/
|
|
static calculateRetryDelay(retryCount, baseDelay = 1000, maxDelay = 30000) {
|
|
const delay = Math.min(baseDelay * Math.pow(2, retryCount - 1), maxDelay);
|
|
return delay;
|
|
}
|
|
|
|
/**
|
|
* 创建可重试错误
|
|
* @param {string} message - 错误消息
|
|
* @param {Object} context - 上下文
|
|
* @returns {Error}
|
|
*/
|
|
static createRetryableError(message, context = {}) {
|
|
const error = new Error(message);
|
|
error.code = 'RETRYABLE';
|
|
error.context = context;
|
|
error.isRetryable = true;
|
|
return error;
|
|
}
|
|
|
|
/**
|
|
* 创建致命错误
|
|
* @param {string} message - 错误消息
|
|
* @param {Object} context - 上下文
|
|
* @returns {Error}
|
|
*/
|
|
static createFatalError(message, context = {}) {
|
|
const error = new Error(message);
|
|
error.code = 'FATAL';
|
|
error.context = context;
|
|
error.isRetryable = false;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
module.exports = ErrorHandler;
|
|
|