UNPKG

@memory-bank/mcp

Version:

Memory-enabled Co-Pilot (MCP) server for managing project documentation and context

82 lines 3.22 kB
export const FILE_SYSTEM_BUSY = 'FILE_SYSTEM_BUSY'; export const TEMPORARY_ERROR = 'TEMPORARY_ERROR'; export const IO_ERROR = 'IO_ERROR'; /** * Utility functions for retrying file system operations */ import { InfrastructureError, InfrastructureErrorCodes } from "../../../shared/errors/InfrastructureError.js"; import { logger } from "../../../shared/utils/logger.js"; /** * Determines if an error is retryable * @param error Error to check * @returns True if the error is retryable, false otherwise */ export function isRetryableError(error) { if (error instanceof Error) { const errorCode = error.code; if (typeof errorCode === 'string') { const retryableCodes = ['EBUSY', 'ETIMEDOUT', 'ECONNRESET', 'EPIPE', 'EAGAIN', 'EACCES', 'EIO']; return retryableCodes.includes(errorCode); } } if (error instanceof InfrastructureError) { return [ FILE_SYSTEM_BUSY, TEMPORARY_ERROR, IO_ERROR ].includes(error.code); } return false; } /** * Retry a function with exponential backoff * @param fn Function to retry * @param options Retry options * @returns Promise resolving to the result of the function * @throws The last error if all retries fail */ export async function withRetry(fn, options = {}) { const maxRetries = options.maxRetries ?? 3; const baseDelay = options.baseDelay ?? 300; const backoffFactor = options.backoffFactor ?? 2; const maxDelay = options.maxDelay ?? 2000; const retryableErrorFilter = options.retryableErrorFilter ?? isRetryableError; let lastError; let attempt = 0; while (attempt <= maxRetries) { try { return await fn(); } catch (error) { lastError = error; attempt++; if (attempt > maxRetries || !retryableErrorFilter(error)) { throw error; } const delay = Math.min(baseDelay * Math.pow(backoffFactor, attempt - 1), maxDelay); logger.warn(`Operation failed (attempt ${attempt}/${maxRetries}), retrying in ${delay}ms: ${error instanceof Error ? error.message : 'Unknown error'}`); await new Promise(resolve => setTimeout(resolve, delay)); } } throw lastError; } /** * Wrapper for file system operations to automatically retry on retryable errors * @param operation Operation name for logging * @param fn Function to execute * @param options Retry options * @returns Promise resolving to the result of the function */ export async function withFileSystemRetry(operation, fn, options = {}) { try { return await withRetry(fn, options); } catch (error) { logger.error(`File system operation '${operation}' failed after retries: ${error instanceof Error ? error.message : 'Unknown error'}`); if (!(error instanceof InfrastructureError)) { throw new InfrastructureError(InfrastructureErrorCodes.FILE_SYSTEM_ERROR, `File system operation '${operation}' failed: ${error instanceof Error ? error.message : 'Unknown error'}`, { originalError: error }); } throw error; } } //# sourceMappingURL=FileSystemRetryUtils.js.map