UNPKG

lanonasis-memory

Version:

Memory as a Service integration - AI-powered memory management with semantic search (Compatible with CLI v3.0.6+)

187 lines 6.88 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_RETRY_OPTIONS = void 0; exports.isRetryableError = isRetryableError; exports.withRetry = withRetry; exports.withProgressAndRetry = withProgressAndRetry; exports.getUserFriendlyErrorMessage = getUserFriendlyErrorMessage; exports.showErrorWithRecovery = showErrorWithRecovery; const vscode = __importStar(require("vscode")); exports.DEFAULT_RETRY_OPTIONS = { maxRetries: 3, initialDelayMs: 1000, maxDelayMs: 10000, backoffMultiplier: 2, retryableErrors: [ /network/i, /timeout/i, /ECONNREFUSED/i, /ENOTFOUND/i, /ETIMEDOUT/i, /rate limit/i, /429/, /503/, /504/ ] }; /** * Determines if an error is retryable based on error message patterns */ function isRetryableError(error, options = exports.DEFAULT_RETRY_OPTIONS) { if (!error) return false; const errorMessage = error instanceof Error ? error.message : String(error); const retryablePatterns = options.retryableErrors || exports.DEFAULT_RETRY_OPTIONS.retryableErrors || []; return retryablePatterns.some(pattern => pattern.test(errorMessage)); } /** * Implements exponential backoff retry logic */ async function withRetry(operation, options = {}, outputChannel) { const opts = { ...exports.DEFAULT_RETRY_OPTIONS, ...options }; let lastError; for (let attempt = 0; attempt <= opts.maxRetries; attempt++) { try { return await operation(); } catch (error) { lastError = error; if (attempt === opts.maxRetries) { // Final attempt failed break; } if (!isRetryableError(error, opts)) { // Error is not retryable throw error; } // Calculate delay with exponential backoff const delay = Math.min(opts.initialDelayMs * Math.pow(opts.backoffMultiplier, attempt), opts.maxDelayMs); const message = `Operation failed (attempt ${attempt + 1}/${opts.maxRetries + 1}). Retrying in ${delay}ms...`; outputChannel?.appendLine(`[Retry] ${message}`); await sleep(delay); } } // All retries exhausted const errorMessage = lastError instanceof Error ? lastError.message : String(lastError); outputChannel?.appendLine(`[Retry] All ${opts.maxRetries + 1} attempts failed. Last error: ${errorMessage}`); throw lastError; } /** * Sleep utility for retry delays */ function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } /** * Wraps an async operation with progress indicator and retry logic */ async function withProgressAndRetry(title, operation, options = {}, outputChannel) { return vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title, cancellable: false }, async () => { return withRetry(operation, options, outputChannel); }); } /** * Creates user-friendly error messages with recovery suggestions */ function getUserFriendlyErrorMessage(error) { const errorMessage = error instanceof Error ? error.message : String(error); // Network errors if (/network|ECONNREFUSED|ENOTFOUND/i.test(errorMessage)) { return { message: 'Unable to connect to Lanonasis servers. Please check your internet connection.', actions: ['Retry', 'Check Settings', 'View Docs'] }; } // Timeout errors if (/timeout|ETIMEDOUT/i.test(errorMessage)) { return { message: 'Request timed out. The server might be slow or unreachable.', actions: ['Retry', 'Check Connection'] }; } // Authentication errors if (/auth|401|403|unauthorized|forbidden/i.test(errorMessage)) { return { message: 'Authentication failed. Please check your API key or re-authenticate.', actions: ['Re-authenticate', 'Clear API Key', 'Get New Key'] }; } // Rate limiting if (/rate limit|429/i.test(errorMessage)) { return { message: 'Rate limit exceeded. Please wait a moment before trying again.', actions: ['Wait and Retry'] }; } // Server errors if (/500|502|503|504|server error/i.test(errorMessage)) { return { message: 'Lanonasis servers are experiencing issues. Please try again later.', actions: ['Retry', 'Check Status Page'] }; } // API key invalid if (/invalid.*key|key.*invalid/i.test(errorMessage)) { return { message: 'Your API key appears to be invalid. Please update your authentication.', actions: ['Re-authenticate', 'Get New Key'] }; } // Generic error return { message: `Operation failed: ${errorMessage}`, actions: ['Retry', 'View Logs'] }; } /** * Shows error with actionable buttons */ async function showErrorWithRecovery(error, outputChannel) { const { message, actions } = getUserFriendlyErrorMessage(error); outputChannel?.appendLine(`[Error] ${message}`); if (error instanceof Error && error.stack) { outputChannel?.appendLine(`[Stack] ${error.stack}`); } if (actions && actions.length > 0) { return vscode.window.showErrorMessage(message, ...actions); } return vscode.window.showErrorMessage(message); } //# sourceMappingURL=errorRecovery.js.map