route-claudecode
Version:
Advanced routing and transformation system for Claude Code outputs to multiple AI providers
132 lines • 4.61 kB
JavaScript
;
/**
* 错误跟踪器 - 专门处理错误日志和分析
* 整合原有的PipelineDebugger错误处理功能
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorTracker = void 0;
class ErrorTracker {
logger;
recentErrors = [];
maxRecentErrors = 100;
constructor(logger) {
this.logger = logger;
}
logToolCallError(error) {
const errorData = {
type: 'tool_call_error',
...error,
timestamp: Date.now()
};
this.addToRecentErrors(errorData);
this.logger.logToolCall(`Tool call error: ${error.errorMessage}`, {
transformationStage: error.transformationStage,
provider: error.provider,
model: error.model,
context: error.context,
port: error.port
}, error.requestId, 'error');
}
logStandardizedError(error) {
const errorData = {
type: 'standardized_error',
...error,
key: this.redactKey(error.key),
timestamp: Date.now()
};
this.addToRecentErrors(errorData);
this.logger.error(`Provider error: ${error.reason}`, {
provider: error.provider,
model: error.model,
errorCode: error.errorCode,
key: this.redactKey(error.key),
port: error.port
}, error.requestId, 'provider_error');
}
logGeneralError(message, error, requestId, stage, context) {
const errorData = {
type: 'general_error',
message,
error: {
name: error?.name,
message: error?.message,
stack: error?.stack
},
requestId,
stage,
context,
timestamp: Date.now()
};
this.addToRecentErrors(errorData);
this.logger.error(message, {
error: errorData.error,
stage,
context
}, requestId, stage);
}
detectToolCallInText(text, requestId, transformationStage, provider, model) {
// 严格检测完整的工具调用结构
const toolCallPatterns = [
/\{\s*"type"\s*:\s*"tool_use"\s*,\s*"id"\s*:\s*"[^"]+"\s*,\s*"name"\s*:\s*"[^"]+"/i,
/\{\s*"id"\s*:\s*"call_[a-zA-Z0-9_-]+"\s*,\s*"type"\s*:\s*"function"/i,
/"tool_calls"\s*:\s*\[\s*\{\s*"id"\s*:\s*"call_/i
];
for (const pattern of toolCallPatterns) {
if (pattern.test(text)) {
this.logToolCallError({
requestId,
errorMessage: `Tool call structure detected in text context`,
transformationStage,
provider,
model,
context: { textSnippet: text.substring(0, 200) },
port: this.logger['config'].port
});
return true;
}
}
return false;
}
redactKey(key) {
if (!key || key.length <= 8)
return '****';
return `${key.substring(0, 4)}****${key.substring(key.length - 4)}`;
}
addToRecentErrors(error) {
this.recentErrors.push({ timestamp: Date.now(), error });
// 保持最近错误数量限制
if (this.recentErrors.length > this.maxRecentErrors) {
this.recentErrors = this.recentErrors.slice(-this.maxRecentErrors);
}
}
getRecentErrors(count = 10) {
return this.recentErrors
.slice(-count)
.reverse()
.map(item => item.error);
}
getErrorStats() {
const stats = {
totalErrors: this.recentErrors.length,
errorTypes: {},
recentErrorsCount: 0
};
const oneHourAgo = Date.now() - (60 * 60 * 1000);
for (const item of this.recentErrors) {
const errorType = item.error.type || 'unknown';
stats.errorTypes[errorType] = (stats.errorTypes[errorType] || 0) + 1;
if (item.timestamp > oneHourAgo) {
stats.recentErrorsCount++;
}
}
return stats;
}
clearOldErrors(maxAgeMs = 24 * 60 * 60 * 1000) {
const cutoffTime = Date.now() - maxAgeMs;
const originalLength = this.recentErrors.length;
this.recentErrors = this.recentErrors.filter(item => item.timestamp > cutoffTime);
return originalLength - this.recentErrors.length;
}
}
exports.ErrorTracker = ErrorTracker;
//# sourceMappingURL=error-tracker.js.map