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
JavaScript
;
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