UNPKG

azureai-optimizer

Version:

AI-Powered Azure Infrastructure Optimization via Model Context Protocol

244 lines 9.72 kB
/** * Error Handling Utilities * Standardized error types and handling for MCP operations */ export var ErrorCode; (function (ErrorCode) { // MCP Standard Error Codes ErrorCode[ErrorCode["PARSE_ERROR"] = -32700] = "PARSE_ERROR"; ErrorCode[ErrorCode["INVALID_REQUEST"] = -32600] = "INVALID_REQUEST"; ErrorCode[ErrorCode["METHOD_NOT_FOUND"] = -32601] = "METHOD_NOT_FOUND"; ErrorCode[ErrorCode["INVALID_PARAMS"] = -32602] = "INVALID_PARAMS"; ErrorCode[ErrorCode["INTERNAL_ERROR"] = -32603] = "INTERNAL_ERROR"; // Custom Error Codes ErrorCode[ErrorCode["UNAUTHORIZED"] = -32000] = "UNAUTHORIZED"; ErrorCode[ErrorCode["FORBIDDEN"] = -32001] = "FORBIDDEN"; ErrorCode[ErrorCode["NOT_FOUND"] = -32002] = "NOT_FOUND"; ErrorCode[ErrorCode["TIMEOUT"] = -32003] = "TIMEOUT"; ErrorCode[ErrorCode["RATE_LIMITED"] = -32004] = "RATE_LIMITED"; ErrorCode[ErrorCode["SERVICE_UNAVAILABLE"] = -32005] = "SERVICE_UNAVAILABLE"; // Azure-specific Error Codes ErrorCode[ErrorCode["AZURE_AUTH_FAILED"] = -33000] = "AZURE_AUTH_FAILED"; ErrorCode[ErrorCode["AZURE_SUBSCRIPTION_NOT_FOUND"] = -33001] = "AZURE_SUBSCRIPTION_NOT_FOUND"; ErrorCode[ErrorCode["AZURE_PERMISSION_DENIED"] = -33002] = "AZURE_PERMISSION_DENIED"; ErrorCode[ErrorCode["AZURE_API_ERROR"] = -33003] = "AZURE_API_ERROR"; ErrorCode[ErrorCode["AZURE_QUOTA_EXCEEDED"] = -33004] = "AZURE_QUOTA_EXCEEDED"; // Tool-specific Error Codes ErrorCode[ErrorCode["TOOL_EXECUTION_FAILED"] = -34000] = "TOOL_EXECUTION_FAILED"; ErrorCode[ErrorCode["TOOL_NOT_FOUND"] = -34001] = "TOOL_NOT_FOUND"; ErrorCode[ErrorCode["TOOL_CONFIGURATION_ERROR"] = -34002] = "TOOL_CONFIGURATION_ERROR"; ErrorCode[ErrorCode["AI_PROVIDER_ERROR"] = -34003] = "AI_PROVIDER_ERROR"; ErrorCode[ErrorCode["DATA_VALIDATION_ERROR"] = -34004] = "DATA_VALIDATION_ERROR"; })(ErrorCode || (ErrorCode = {})); export class MCPError extends Error { code; data; constructor(code, message, data) { super(message); this.name = 'MCPError'; this.code = code; this.data = data; // Ensure proper prototype chain Object.setPrototypeOf(this, MCPError.prototype); } toJSON() { return { code: this.code, message: this.message, data: this.data }; } static fromError(error, code = ErrorCode.INTERNAL_ERROR) { if (error instanceof MCPError) { return error; } const message = error instanceof Error ? error.message : String(error); const data = error instanceof Error ? { stack: error.stack } : undefined; return new MCPError(code, message, data); } static isRetryable(error) { const retryableCodes = [ ErrorCode.TIMEOUT, ErrorCode.RATE_LIMITED, ErrorCode.SERVICE_UNAVAILABLE, ErrorCode.AZURE_API_ERROR ]; return retryableCodes.includes(error.code); } } export class AzureError extends MCPError { azureErrorCode; requestId; constructor(code, message, azureErrorCode, requestId, data) { super(code, message, data); this.name = 'AzureError'; if (azureErrorCode !== undefined) { this.azureErrorCode = azureErrorCode; } if (requestId !== undefined) { this.requestId = requestId; } } static fromAzureResponse(response) { const errorCode = response.error?.code || 'UnknownError'; const message = response.error?.message || 'Unknown Azure error'; const requestId = response.headers?.['x-ms-request-id']; let mcpCode; switch (errorCode) { case 'AuthenticationFailed': case 'InvalidAuthenticationToken': mcpCode = ErrorCode.AZURE_AUTH_FAILED; break; case 'SubscriptionNotFound': mcpCode = ErrorCode.AZURE_SUBSCRIPTION_NOT_FOUND; break; case 'AuthorizationFailed': case 'Forbidden': mcpCode = ErrorCode.AZURE_PERMISSION_DENIED; break; case 'QuotaExceeded': case 'TooManyRequests': mcpCode = ErrorCode.AZURE_QUOTA_EXCEEDED; break; default: mcpCode = ErrorCode.AZURE_API_ERROR; } return new AzureError(mcpCode, message, errorCode, requestId, response); } } export class ToolError extends MCPError { toolName; executionContext; constructor(toolName, code, message, executionContext, data) { super(code, message, data); this.name = 'ToolError'; this.toolName = toolName; this.executionContext = executionContext; } static toolNotFound(toolName) { return new ToolError(toolName, ErrorCode.TOOL_NOT_FOUND, `Tool '${toolName}' not found`); } static executionFailed(toolName, error, context) { const message = error instanceof Error ? error.message : String(error); return new ToolError(toolName, ErrorCode.TOOL_EXECUTION_FAILED, `Tool '${toolName}' execution failed: ${message}`, context, error); } static configurationError(toolName, message) { return new ToolError(toolName, ErrorCode.TOOL_CONFIGURATION_ERROR, `Tool '${toolName}' configuration error: ${message}`); } } export class ValidationError extends MCPError { field; value; constructor(message, field, value) { super(ErrorCode.DATA_VALIDATION_ERROR, message, { field, value }); this.name = 'ValidationError'; if (field !== undefined) { this.field = field; } this.value = value; } static required(field) { return new ValidationError(`Field '${field}' is required`, field); } static invalid(field, value, reason) { const message = reason ? `Field '${field}' has invalid value: ${reason}` : `Field '${field}' has invalid value`; return new ValidationError(message, field, value); } static type(field, expectedType, actualType) { return new ValidationError(`Field '${field}' must be of type ${expectedType}, got ${actualType}`, field); } } export class AIProviderError extends MCPError { provider; originalError; constructor(provider, message, originalError) { super(ErrorCode.AI_PROVIDER_ERROR, message, originalError); this.name = 'AIProviderError'; this.provider = provider; this.originalError = originalError; } static notConfigured(provider) { return new AIProviderError(provider, `AI provider '${provider}' is not configured`); } static apiError(provider, error) { const message = error instanceof Error ? error.message : String(error); return new AIProviderError(provider, `AI provider '${provider}' API error: ${message}`, error); } static quotaExceeded(provider) { return new AIProviderError(provider, `AI provider '${provider}' quota exceeded`); } } export function handleError(error) { // Convert various error types to MCPError if (error instanceof MCPError) { return error; } if (error instanceof Error) { // Check for specific error patterns if (error.message.includes('authentication') || error.message.includes('unauthorized')) { return new MCPError(ErrorCode.UNAUTHORIZED, error.message); } if (error.message.includes('permission') || error.message.includes('forbidden')) { return new MCPError(ErrorCode.FORBIDDEN, error.message); } if (error.message.includes('not found')) { return new MCPError(ErrorCode.NOT_FOUND, error.message); } if (error.message.includes('timeout')) { return new MCPError(ErrorCode.TIMEOUT, error.message); } if (error.message.includes('rate limit')) { return new MCPError(ErrorCode.RATE_LIMITED, error.message); } // Default to internal error return new MCPError(ErrorCode.INTERNAL_ERROR, error.message, { stack: error.stack }); } // Handle non-Error objects return new MCPError(ErrorCode.INTERNAL_ERROR, String(error)); } export function isRetryableError(error) { if (error instanceof MCPError) { return MCPError.isRetryable(error); } // Check for common retryable error patterns const errorMessage = String(error).toLowerCase(); const retryablePatterns = [ 'timeout', 'rate limit', 'service unavailable', 'temporary failure', 'connection reset', 'network error' ]; return retryablePatterns.some(pattern => errorMessage.includes(pattern)); } export function getErrorSeverity(error) { switch (error.code) { case ErrorCode.PARSE_ERROR: case ErrorCode.INVALID_REQUEST: case ErrorCode.INVALID_PARAMS: return 'medium'; case ErrorCode.METHOD_NOT_FOUND: case ErrorCode.NOT_FOUND: case ErrorCode.TOOL_NOT_FOUND: return 'low'; case ErrorCode.UNAUTHORIZED: case ErrorCode.FORBIDDEN: case ErrorCode.AZURE_AUTH_FAILED: case ErrorCode.AZURE_PERMISSION_DENIED: return 'high'; case ErrorCode.INTERNAL_ERROR: case ErrorCode.AZURE_API_ERROR: case ErrorCode.TOOL_EXECUTION_FAILED: return 'critical'; case ErrorCode.TIMEOUT: case ErrorCode.RATE_LIMITED: case ErrorCode.SERVICE_UNAVAILABLE: return 'medium'; default: return 'medium'; } } //# sourceMappingURL=errors.js.map