UNPKG

msexchange-mcp

Version:

MCP server for Microsoft Exchange/Outlook email operations via Microsoft Graph API

194 lines 7.07 kB
/** * Error classification and handling utilities */ export var ErrorType; (function (ErrorType) { ErrorType["AUTHENTICATION"] = "authentication"; ErrorType["NETWORK"] = "network"; ErrorType["API_LIMIT"] = "api_limit"; ErrorType["VALIDATION"] = "validation"; ErrorType["NOT_FOUND"] = "not_found"; ErrorType["PERMISSION"] = "permission"; ErrorType["SYNTAX"] = "syntax"; ErrorType["UNKNOWN"] = "unknown"; })(ErrorType || (ErrorType = {})); /** * Classify errors and provide actionable suggestions */ export function classifyError(error) { const errorMessage = error instanceof Error ? error.message : String(error); const lowerMessage = errorMessage.toLowerCase(); // Authentication errors if (lowerMessage.includes('unauthorized') || lowerMessage.includes('401') || lowerMessage.includes('authentication') || lowerMessage.includes('invalid token') || lowerMessage.includes('expired token')) { return { type: ErrorType.AUTHENTICATION, message: 'Authentication failed', originalError: error instanceof Error ? error : undefined, suggestions: [ 'Check if your credentials are valid', 'Try re-authenticating with the device code flow', 'Ensure your Azure AD app has the required permissions' ], retryable: false }; } // Network errors if (lowerMessage.includes('enotfound') || lowerMessage.includes('etimedout') || lowerMessage.includes('econnrefused') || lowerMessage.includes('network')) { return { type: ErrorType.NETWORK, message: 'Network connection error', originalError: error instanceof Error ? error : undefined, suggestions: [ 'Check your internet connection', 'Verify the Microsoft Graph API is accessible', 'Try again in a few moments' ], retryable: true }; } // API rate limit errors if (lowerMessage.includes('429') || lowerMessage.includes('rate limit') || lowerMessage.includes('too many requests')) { return { type: ErrorType.API_LIMIT, message: 'API rate limit exceeded', originalError: error instanceof Error ? error : undefined, suggestions: [ 'Wait a few minutes before retrying', 'Reduce the frequency of requests', 'Use smaller batch sizes for queries' ], retryable: true }; } // Validation errors if (lowerMessage.includes('invalid') || lowerMessage.includes('bad request') || lowerMessage.includes('400') || lowerMessage.includes('malformed')) { return { type: ErrorType.VALIDATION, message: 'Invalid request parameters', originalError: error instanceof Error ? error : undefined, suggestions: [ 'Check the format of your search query', 'Ensure email addresses are valid', 'Remove special characters from search terms', 'Use proper date formats (YYYY-MM-DD)' ], retryable: false }; } // Not found errors if (lowerMessage.includes('not found') || lowerMessage.includes('404') || lowerMessage.includes('does not exist')) { return { type: ErrorType.NOT_FOUND, message: 'Resource not found', originalError: error instanceof Error ? error : undefined, suggestions: [ 'Verify the email ID is correct', 'Check if the email was deleted', 'Ensure you have access to this mailbox' ], retryable: false }; } // Permission errors if (lowerMessage.includes('forbidden') || lowerMessage.includes('403') || lowerMessage.includes('permission') || lowerMessage.includes('access denied')) { return { type: ErrorType.PERMISSION, message: 'Permission denied', originalError: error instanceof Error ? error : undefined, suggestions: [ 'Check if you have the required permissions for this operation', 'Verify the Azure AD app has proper Graph API permissions', 'Contact your administrator for access' ], retryable: false }; } // OData syntax errors if (lowerMessage.includes('syntax') || lowerMessage.includes('odata') || lowerMessage.includes('filter') || lowerMessage.includes('restriction or sort order is too complex')) { return { type: ErrorType.SYNTAX, message: 'Query syntax error', originalError: error instanceof Error ? error : undefined, suggestions: [ 'Simplify your search query', 'Remove special characters from search terms', 'Use quotes for exact phrases', 'Try searching without date filters' ], retryable: false }; } // Unknown errors return { type: ErrorType.UNKNOWN, message: 'An unexpected error occurred', originalError: error instanceof Error ? error : undefined, suggestions: [ 'Try again with a simpler query', 'Check the server logs for more details', 'Contact support if the issue persists' ], retryable: true }; } /** * Format error response for user display */ export function formatErrorResponse(classified) { const parts = [ `❌ ${classified.message}`, '', 'Suggestions:', ...classified.suggestions.map(s => `• ${s}`), ]; if (classified.retryable) { parts.push('', '🔄 This error may be temporary. Please try again.'); } if (process.env.DEBUG && classified.originalError) { parts.push('', `Debug info: ${classified.originalError.message}`); } return parts.join('\n'); } /** * Retry with exponential backoff for retryable errors */ export async function retryWithBackoff(operation, maxRetries = 3, baseDelay = 1000) { let lastError; for (let attempt = 0; attempt < maxRetries; attempt++) { try { return await operation(); } catch (error) { lastError = error; const classified = classifyError(error); if (!classified.retryable || attempt === maxRetries - 1) { throw error; } const delay = baseDelay * Math.pow(2, attempt); console.error(`Retrying after ${delay}ms (attempt ${attempt + 1}/${maxRetries})`); await new Promise(resolve => setTimeout(resolve, delay)); } } throw lastError; } //# sourceMappingURL=errorClassifier.js.map