Skip to main content
Glama
telemetry-error.js5.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TelemetryErrorAggregator = exports.TelemetryCircuitBreaker = exports.TelemetryError = exports.TelemetryErrorType = void 0; const logger_1 = require("../utils/logger"); var telemetry_types_1 = require("./telemetry-types"); Object.defineProperty(exports, "TelemetryErrorType", { enumerable: true, get: function () { return telemetry_types_1.TelemetryErrorType; } }); class TelemetryError extends Error { constructor(type, message, context, retryable = false) { super(message); this.name = 'TelemetryError'; this.type = type; this.context = context; this.timestamp = Date.now(); this.retryable = retryable; Object.setPrototypeOf(this, TelemetryError.prototype); } toContext() { return { type: this.type, message: this.message, context: this.context, timestamp: this.timestamp, retryable: this.retryable }; } log() { const logContext = { type: this.type, message: this.message, ...this.context }; if (this.retryable) { logger_1.logger.debug('Retryable telemetry error:', logContext); } else { logger_1.logger.debug('Non-retryable telemetry error:', logContext); } } } exports.TelemetryError = TelemetryError; class TelemetryCircuitBreaker { constructor(failureThreshold = 5, resetTimeout = 60000, halfOpenRequests = 3) { this.failureCount = 0; this.lastFailureTime = 0; this.state = 'closed'; this.halfOpenCount = 0; this.failureThreshold = failureThreshold; this.resetTimeout = resetTimeout; this.halfOpenRequests = halfOpenRequests; } shouldAllow() { const now = Date.now(); switch (this.state) { case 'closed': return true; case 'open': if (now - this.lastFailureTime > this.resetTimeout) { this.state = 'half-open'; this.halfOpenCount = 0; logger_1.logger.debug('Circuit breaker transitioning to half-open'); return true; } return false; case 'half-open': if (this.halfOpenCount < this.halfOpenRequests) { this.halfOpenCount++; return true; } return false; default: return false; } } recordSuccess() { if (this.state === 'half-open') { if (this.halfOpenCount >= this.halfOpenRequests) { this.state = 'closed'; this.failureCount = 0; logger_1.logger.debug('Circuit breaker closed after successful recovery'); } } else if (this.state === 'closed') { this.failureCount = 0; } } recordFailure(error) { this.failureCount++; this.lastFailureTime = Date.now(); if (this.state === 'half-open') { this.state = 'open'; logger_1.logger.debug('Circuit breaker opened from half-open state', { error: error?.message }); } else if (this.state === 'closed' && this.failureCount >= this.failureThreshold) { this.state = 'open'; logger_1.logger.debug(`Circuit breaker opened after ${this.failureCount} failures`, { error: error?.message }); } } getState() { return { state: this.state, failureCount: this.failureCount, canRetry: this.shouldAllow() }; } reset() { this.state = 'closed'; this.failureCount = 0; this.lastFailureTime = 0; this.halfOpenCount = 0; } } exports.TelemetryCircuitBreaker = TelemetryCircuitBreaker; class TelemetryErrorAggregator { constructor() { this.errors = new Map(); this.errorDetails = []; this.maxDetails = 100; } record(error) { const count = this.errors.get(error.type) || 0; this.errors.set(error.type, count + 1); this.errorDetails.push(error.toContext()); if (this.errorDetails.length > this.maxDetails) { this.errorDetails.shift(); } } getStats() { const errorsByType = {}; let totalErrors = 0; let mostCommonError; let maxCount = 0; for (const [type, count] of this.errors.entries()) { errorsByType[type] = count; totalErrors += count; if (count > maxCount) { maxCount = count; mostCommonError = type; } } return { totalErrors, errorsByType, mostCommonError, recentErrors: this.errorDetails.slice(-10) }; } reset() { this.errors.clear(); this.errorDetails = []; } } exports.TelemetryErrorAggregator = TelemetryErrorAggregator; //# sourceMappingURL=telemetry-error.js.map

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/czlonkowski/n8n-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server