reagentbuilder
Version:
An enterprise-grade AI agent framework based on LangChain and LangGraph, featuring dynamic tools, interceptors, breakpoints, and performance monitoring.
221 lines • 8.48 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.errorHandler = exports.ErrorHandler = exports.ReAgentError = exports.ErrorSeverity = exports.ErrorType = void 0;
const logger_js_1 = require("./logger.js");
const performance_js_1 = require("./performance.js");
// ============ 统一错误处理类 ============
var ErrorType;
(function (ErrorType) {
ErrorType["CONFIGURATION"] = "CONFIGURATION";
ErrorType["VALIDATION"] = "VALIDATION";
ErrorType["RUNTIME"] = "RUNTIME";
ErrorType["NETWORK"] = "NETWORK";
ErrorType["TIMEOUT"] = "TIMEOUT";
ErrorType["RESOURCE"] = "RESOURCE";
ErrorType["PERMISSION"] = "PERMISSION";
ErrorType["CRITICAL"] = "CRITICAL";
})(ErrorType || (exports.ErrorType = ErrorType = {}));
var ErrorSeverity;
(function (ErrorSeverity) {
ErrorSeverity["LOW"] = "LOW";
ErrorSeverity["MEDIUM"] = "MEDIUM";
ErrorSeverity["HIGH"] = "HIGH";
ErrorSeverity["CRITICAL"] = "CRITICAL";
})(ErrorSeverity || (exports.ErrorSeverity = ErrorSeverity = {}));
class ReAgentError extends Error {
constructor(message, type = ErrorType.RUNTIME, severity = ErrorSeverity.MEDIUM, context = {}, code, retryable = false) {
super(message);
this.name = 'ReAgentError';
this.type = type;
this.severity = severity;
this.context = {
...context,
timestamp: Date.now(),
stackTrace: this.stack
};
this.code = code;
this.retryable = retryable;
this.timestamp = Date.now();
// 保持正确的原型链
Object.setPrototypeOf(this, ReAgentError.prototype);
}
toJSON() {
return {
name: this.name,
message: this.message,
type: this.type,
severity: this.severity,
context: this.context,
code: this.code,
retryable: this.retryable,
timestamp: this.timestamp,
stack: this.stack
};
}
toString() {
const parts = [
`[${this.type}:${this.severity}]`,
this.code ? `[${this.code}]` : '',
this.message,
this.context.component ? `(Component: ${this.context.component})` : '',
this.context.operation ? `(Operation: ${this.context.operation})` : ''
].filter(Boolean);
return parts.join(' ');
}
}
exports.ReAgentError = ReAgentError;
class ErrorHandler {
constructor() {
this.errorCounts = new Map();
this.lastErrors = new Map();
this.maxSimilarErrors = 10;
this.similarErrorWindow = 60000; // 1分钟
}
static getInstance() {
if (!ErrorHandler.instance) {
ErrorHandler.instance = new ErrorHandler();
}
return ErrorHandler.instance;
}
// 创建错误
static createError(message, type = ErrorType.RUNTIME, severity = ErrorSeverity.MEDIUM, context = {}, code, retryable = false) {
return new ReAgentError(message, type, severity, context, code, retryable);
}
// 处理错误
handleError(error, context = {}) {
let reAgentError;
if (error instanceof ReAgentError) {
// 合并上下文
reAgentError = new ReAgentError(error.message, error.type, error.severity, { ...error.context, ...context }, error.code, error.retryable);
}
else {
// 转换普通错误
reAgentError = new ReAgentError(error.message, ErrorType.RUNTIME, ErrorSeverity.MEDIUM, { ...context, originalError: error.name }, undefined, false);
}
// 防重复错误
if (this.shouldSuppressDuplicateError(reAgentError)) {
return reAgentError;
}
// 记录错误
this.logError(reAgentError);
// 性能监控
performance_js_1.perfMonitor.recordError(`${reAgentError.type}.${reAgentError.severity}`);
performance_js_1.perfMonitor.incrementCounter('errors.total');
performance_js_1.perfMonitor.incrementCounter(`errors.${reAgentError.type.toLowerCase()}`);
return reAgentError;
}
shouldSuppressDuplicateError(error) {
const errorKey = `${error.type}:${error.message}`;
const now = Date.now();
const lastTime = this.lastErrors.get(errorKey) || 0;
const count = this.errorCounts.get(errorKey) || 0;
if (now - lastTime < this.similarErrorWindow && count >= this.maxSimilarErrors) {
return true;
}
this.lastErrors.set(errorKey, now);
this.errorCounts.set(errorKey, count + 1);
// 清理过期的错误计数
if (now - lastTime > this.similarErrorWindow) {
this.errorCounts.set(errorKey, 1);
}
return false;
}
logError(error) {
const logMessage = `${error.toString()}`;
const logDetails = {
type: error.type,
severity: error.severity,
context: error.context,
code: error.code,
retryable: error.retryable
};
switch (error.severity) {
case ErrorSeverity.CRITICAL:
logger_js_1.logger.error(logMessage, logDetails);
break;
case ErrorSeverity.HIGH:
logger_js_1.logger.error(logMessage, logDetails);
break;
case ErrorSeverity.MEDIUM:
logger_js_1.logger.warn(logMessage, logDetails);
break;
case ErrorSeverity.LOW:
logger_js_1.logger.debug(logMessage, logDetails);
break;
}
}
// 包装异步函数,自动错误处理
async wrapAsync(fn, context, errorType = ErrorType.RUNTIME, severity = ErrorSeverity.MEDIUM) {
try {
return await fn();
}
catch (error) {
throw this.handleError(error instanceof Error ? error : new Error(String(error)), context);
}
}
// 包装同步函数,自动错误处理
wrap(fn, context, errorType = ErrorType.RUNTIME, severity = ErrorSeverity.MEDIUM) {
try {
return fn();
}
catch (error) {
throw this.handleError(error instanceof Error ? error : new Error(String(error)), context);
}
}
// 重试机制
async retry(fn, context, maxRetries = 3, delayMs = 1000, backoffMultiplier = 2) {
let lastError = null;
let currentDelay = delayMs;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
}
catch (error) {
lastError = error instanceof Error ? error : new Error(String(error));
const reAgentError = this.handleError(lastError, {
...context,
attempt: attempt + 1,
maxRetries
});
if (attempt === maxRetries - 1 || !reAgentError.retryable) {
throw reAgentError;
}
logger_js_1.logger.warn(`重试操作 (${attempt + 1}/${maxRetries}),${currentDelay}ms后重试`, {
operation: context.operation,
error: reAgentError.message
});
await new Promise(resolve => setTimeout(resolve, currentDelay));
currentDelay *= backoffMultiplier;
}
}
throw this.handleError(lastError, context);
}
// 获取错误统计
getErrorStats() {
const stats = {
totalUniqueErrors: this.errorCounts.size,
errorCounts: Object.fromEntries(this.errorCounts),
recentErrors: []
};
const now = Date.now();
for (const [errorKey, lastTime] of this.lastErrors.entries()) {
if (now - lastTime < this.similarErrorWindow) {
stats.recentErrors.push({
error: errorKey,
lastOccurred: new Date(lastTime).toISOString(),
count: this.errorCounts.get(errorKey) || 0
});
}
}
return stats;
}
// 清理错误统计
clearErrorStats() {
this.errorCounts.clear();
this.lastErrors.clear();
logger_js_1.logger.debug('错误统计已清理');
}
}
exports.ErrorHandler = ErrorHandler;
exports.errorHandler = ErrorHandler.getInstance();
//# sourceMappingURL=error-handler.js.map