Skip to main content
Glama

firewalla-mcp-server

error-classification.ts17.5 kB
/** * Error Classification and Standardization Utilities for Firewalla MCP Server * Provides consistent error classification, response formatting, and troubleshooting guidance */ import { ErrorType, createErrorResponse } from './error-handler.js'; /** * Common error patterns and their classifications */ export const ERROR_PATTERNS = { // Network and connectivity errors NETWORK_ERRORS: [ /ECONNREFUSED/i, /ENOTFOUND/i, /ETIMEDOUT/i, /network.*error/i, /connection.*refused/i, /connection.*reset/i, /dns.*error/i, ], // Authentication and authorization errors AUTH_ERRORS: [ /unauthorized/i, /authentication.*failed/i, /invalid.*token/i, /access.*denied/i, /forbidden/i, /401/, /403/, ], // Resource not found errors NOT_FOUND_ERRORS: [ /not.*found/i, /does.*not.*exist/i, /resource.*not.*found/i, /404/, /no.*such.*resource/i, ], // Rate limiting errors RATE_LIMIT_ERRORS: [ /rate.*limit/i, /too.*many.*requests/i, /429/, /quota.*exceeded/i, /throttle/i, ], // Timeout errors (actual timeouts, not misclassified) TIMEOUT_ERRORS: [ /timeout/i, /timed.*out/i, /operation.*timeout/i, /request.*timeout/i, ], // Validation errors VALIDATION_ERRORS: [ /validation.*failed/i, /invalid.*parameter/i, /parameter.*required/i, /missing.*parameter/i, /bad.*request/i, /400/, ], // Cache-related errors CACHE_ERRORS: [ /cache.*error/i, /cache.*miss/i, /cache.*timeout/i, /redis.*error/i, /memcached.*error/i, ], // Correlation-specific errors (entity relationship and cross-reference issues) CORRELATION_ERRORS: [ /correlation.*failed/i, /cross.*reference.*failed/i, /field.*mapping.*error/i, /entity.*relationship.*error/i, /correlation.*timeout/i, /invalid.*correlation.*field/i, /too.*many.*correlation.*fields/i, ], // Search-specific errors (query parsing and search execution issues) SEARCH_ERRORS: [ /search.*failed/i, /query.*failed/i, /query.*syntax.*error/i, /invalid.*search.*field/i, /search.*limit.*exceeded/i, /search.*timeout/i, /index.*error/i, /filter.*error/i, /search.*parse.*error/i, ], } as const; /** * Error context information for better troubleshooting */ export interface ErrorContext { /** Tool name where error occurred */ toolName: string; /** Operation being performed */ operation?: string; /** Parameters passed to the operation */ parameters?: Record<string, unknown>; /** Original error object */ originalError?: Error; /** Additional context information */ context?: Record<string, unknown>; } /** * Standardized troubleshooting suggestions by error type */ export const TROUBLESHOOTING_GUIDES = { [ErrorType.VALIDATION_ERROR]: [ 'Check that all required parameters are provided', 'Verify parameter types and formats match expectations', 'Review parameter value ranges and constraints', 'Ensure special characters are properly escaped', ], [ErrorType.AUTHENTICATION_ERROR]: [ 'Verify your API token is valid and not expired', 'Check that the token has necessary permissions', 'Ensure the MSP domain is correct', 'Try regenerating your access token', ], [ErrorType.API_ERROR]: [ 'Check if the Firewalla API is accessible', 'Verify network connectivity to the MSP endpoint', 'Ensure the resource exists and is accessible', 'Check for API service outages or maintenance', ], [ErrorType.NETWORK_ERROR]: [ 'Verify internet connectivity', 'Check firewall and proxy settings', 'Ensure DNS resolution is working', 'Try again after a brief delay', ], [ErrorType.TIMEOUT_ERROR]: [ 'Reduce the scope of your query (smaller limit, shorter time range)', 'Try breaking large operations into smaller chunks', 'Check for network latency issues', 'Consider using pagination for large datasets', ], [ErrorType.RATE_LIMIT_ERROR]: [ 'Implement delays between API calls', 'Reduce the frequency of requests', 'Use caching to minimize duplicate requests', 'Contact support if limits seem unreasonable', ], [ErrorType.CACHE_ERROR]: [ 'Clear local cache and retry', 'Check cache service availability', 'Try disabling cache temporarily', 'Verify cache configuration settings', ], [ErrorType.CORRELATION_ERROR]: [ 'Simplify correlation queries', 'Check field names and availability', 'Reduce the number of correlation fields', 'Verify data types match for correlation', ], [ErrorType.SEARCH_ERROR]: [ 'Verify search query syntax', 'Check field names and operators', 'Simplify complex search expressions', 'Try using exact matches instead of wildcards', ], [ErrorType.SERVICE_UNAVAILABLE]: [ 'Check if the MCP server is running in safe mode', 'Verify the WAVE0_ENABLED environment variable is not set to false', 'Wait for service maintenance to complete', 'Try again after a short delay', ], [ErrorType.TOOL_DISABLED]: [ 'Check if the tool is listed in MCP_DISABLED_TOOLS environment variable', 'Verify the tool name is spelled correctly', 'Contact administrator to enable the tool', 'Use alternative tools if available', ], [ErrorType.UNKNOWN_ERROR]: [ 'Check the detailed error message for clues', 'Try the operation again after a short delay', 'Verify all parameters are correct', 'Contact support if the issue persists', ], } as const; /** * Documentation links by error type */ export const DOCUMENTATION_LINKS = { [ErrorType.VALIDATION_ERROR]: '/docs/parameter-validation-guide.md', [ErrorType.AUTHENTICATION_ERROR]: '/docs/authentication-guide.md', [ErrorType.API_ERROR]: '/docs/firewalla-api-reference.md', [ErrorType.NETWORK_ERROR]: '/docs/troubleshooting-guide.md#network-issues', [ErrorType.TIMEOUT_ERROR]: '/docs/performance-optimization-guide.md', [ErrorType.RATE_LIMIT_ERROR]: '/docs/rate-limiting-guide.md', [ErrorType.CACHE_ERROR]: '/docs/caching-guide.md', [ErrorType.CORRELATION_ERROR]: '/docs/correlation-guide.md', [ErrorType.SEARCH_ERROR]: '/docs/query-syntax-guide.md', [ErrorType.SERVICE_UNAVAILABLE]: '/docs/troubleshooting-guide.md', [ErrorType.TOOL_DISABLED]: '/docs/feature-flags-guide.md', [ErrorType.UNKNOWN_ERROR]: '/docs/troubleshooting-guide.md', } as const; /** * Error classification utility */ export class ErrorClassifier { /** * Classify an error based on its message and context with improved timeout detection */ static classifyError(error: Error | string, context?: ErrorContext): ErrorType { const errorMessage = typeof error === 'string' ? error : error.message; const errorString = errorMessage.toLowerCase(); // First, check for likely misclassified timeouts if (errorString.includes('timeout')) { const executionTime = context?.context?.executionTime as number | undefined; if (this.isLikelyMisclassifiedTimeout(error, executionTime)) { // This looks like a validation or other error that mentions timeout // Check for validation patterns specifically if (ERROR_PATTERNS.VALIDATION_ERRORS.some(pattern => pattern.test(errorString))) { return ErrorType.VALIDATION_ERROR; } if (ERROR_PATTERNS.AUTH_ERRORS.some(pattern => pattern.test(errorString))) { return ErrorType.AUTHENTICATION_ERROR; } if (ERROR_PATTERNS.NETWORK_ERRORS.some(pattern => pattern.test(errorString))) { return ErrorType.NETWORK_ERROR; } } else { // This appears to be a real timeout return ErrorType.TIMEOUT_ERROR; } } // Priority-based classification to handle pattern conflicts // Higher priority error types are checked first // 1. Authentication errors (highest priority - security critical) if (ERROR_PATTERNS.AUTH_ERRORS.some(pattern => pattern.test(errorString))) { return ErrorType.AUTHENTICATION_ERROR; } // 2. Validation errors (high priority - parameter issues) if (ERROR_PATTERNS.VALIDATION_ERRORS.some(pattern => pattern.test(errorString))) { return ErrorType.VALIDATION_ERROR; } // 3. Rate limiting errors (high priority - service protection) if (ERROR_PATTERNS.RATE_LIMIT_ERRORS.some(pattern => pattern.test(errorString))) { return ErrorType.RATE_LIMIT_ERROR; } // 4. Network errors (medium priority - infrastructure issues) if (ERROR_PATTERNS.NETWORK_ERRORS.some(pattern => pattern.test(errorString))) { return ErrorType.NETWORK_ERROR; } // 5. Timeout errors (only real timeouts reach here) if (ERROR_PATTERNS.TIMEOUT_ERRORS.some(pattern => pattern.test(errorString))) { return ErrorType.TIMEOUT_ERROR; } // 6. Cache errors (medium priority) if (ERROR_PATTERNS.CACHE_ERRORS.some(pattern => pattern.test(errorString))) { return ErrorType.CACHE_ERROR; } // 7. Search-specific errors if (ERROR_PATTERNS.SEARCH_ERRORS.some(pattern => pattern.test(errorString))) { return ErrorType.SEARCH_ERROR; } // 8. Correlation errors if (ERROR_PATTERNS.CORRELATION_ERRORS.some(pattern => pattern.test(errorString))) { return ErrorType.CORRELATION_ERROR; } // 9. API errors (including not found - lower priority as these are more generic) if (ERROR_PATTERNS.NOT_FOUND_ERRORS.some(pattern => pattern.test(errorString))) { return ErrorType.API_ERROR; } // Context-based classification for edge cases if (context?.operation?.includes('search') || context?.operation?.includes('query')) { return ErrorType.SEARCH_ERROR; } if (context?.operation?.includes('auth') || context?.operation?.includes('login')) { return ErrorType.AUTHENTICATION_ERROR; } if (context?.parameters && Object.keys(context.parameters).length > 0) { // If we have parameters but no clear pattern match, likely a validation issue return ErrorType.VALIDATION_ERROR; } return ErrorType.UNKNOWN_ERROR; } /** * Create a standardized error response with proper classification */ static createStandardizedErrorResponse( error: Error | string, context: ErrorContext ) { const errorType = this.classifyError(error, context); const errorMessage = typeof error === 'string' ? error : error.message; // Create enhanced error details const errorDetails = { tool: context.toolName, operation: context.operation, error_type: errorType, original_error: errorMessage, timestamp: new Date().toISOString(), parameters: context.parameters, context: context.context, troubleshooting: TROUBLESHOOTING_GUIDES[errorType], documentation: DOCUMENTATION_LINKS[errorType], }; // Generate user-friendly error message const userMessage = this.generateUserFriendlyMessage(errorType, errorMessage, context); return createErrorResponse( context.toolName, userMessage, errorType, errorDetails, undefined, // validation_errors - will be set separately if needed { endpoint: context.operation, parameters: context.parameters, userAgent: 'Firewalla MCP Server', } ); } /** * Generate user-friendly error messages */ private static generateUserFriendlyMessage( errorType: ErrorType, originalMessage: string, context: ErrorContext ): string { const operation = context.operation || 'operation'; switch (errorType) { case ErrorType.VALIDATION_ERROR: return `Parameter validation failed for ${operation}`; case ErrorType.AUTHENTICATION_ERROR: return `Authentication failed - please check your API credentials`; case ErrorType.NETWORK_ERROR: return `Network error occurred while performing ${operation}`; case ErrorType.TIMEOUT_ERROR: return `Operation ${operation} timed out - try reducing query scope`; case ErrorType.RATE_LIMIT_ERROR: return `Rate limit exceeded - please slow down your requests`; case ErrorType.API_ERROR: if (originalMessage.includes('not found') || originalMessage.includes('404')) { return `Resource not found for ${operation}`; } return `API error occurred during ${operation}`; case ErrorType.CACHE_ERROR: return `Cache error during ${operation} - operation may be slower`; case ErrorType.CORRELATION_ERROR: return `Correlation analysis failed - try simplifying the query`; case ErrorType.SEARCH_ERROR: return `Search operation failed - check query syntax`; case ErrorType.SERVICE_UNAVAILABLE: return `Service is temporarily unavailable for ${operation}`; case ErrorType.TOOL_DISABLED: return `Tool is currently disabled for ${operation}`; case ErrorType.UNKNOWN_ERROR: return `Unknown error occurred during ${operation}: ${originalMessage}`; default: return `${operation} failed: ${originalMessage}`; } } /** * Enhance existing error responses with standardized classification */ static enhanceErrorResponse( existingResponse: any, error: Error | string, context: ErrorContext ): any { const errorType = this.classifyError(error, context); if (existingResponse.content?.[0]?.text) { try { const errorData = JSON.parse(existingResponse.content[0].text); // Enhance with standardized information errorData.errorType = errorType; errorData.troubleshooting = TROUBLESHOOTING_GUIDES[errorType]; errorData.documentation = DOCUMENTATION_LINKS[errorType]; errorData.classification = { auto_classified: true, confidence: 'high', pattern_matched: true, }; existingResponse.content[0].text = JSON.stringify(errorData, null, 2); } catch { // If parsing fails, leave response as-is } } return existingResponse; } /** * Check if an error is likely a timeout that should be reclassified */ static isLikelyMisclassifiedTimeout( error: Error | string, duration?: number ): boolean { const errorMessage = typeof error === 'string' ? error : error.message; const errorString = errorMessage.toLowerCase(); // If duration is very short (< 100ms) but error mentions timeout, // it's likely a misclassification if (duration && duration < 100 && errorString.includes('timeout')) { return true; } // If duration is very long (> 30s), it's probably a real timeout if (duration && duration > 30000) { return false; } // Check for patterns that suggest immediate failure rather than actual timeout const immediateFailurePatterns = [ /connection.*refused/i, /not.*found/i, /invalid.*parameter/i, /parameter.*required/i, /missing.*parameter/i, /authentication.*failed/i, /unauthorized/i, /forbidden/i, /bad.*request/i, /validation.*failed/i, /syntax.*error/i, /parse.*error/i, /format.*error/i, /400/, /401/, /403/, /404/, ]; // If it contains timeout but also contains immediate failure patterns, // it's likely misclassified if (errorString.includes('timeout') && immediateFailurePatterns.some(pattern => pattern.test(errorString))) { return true; } // Check for specific timeout error contexts that suggest real timeouts const realTimeoutIndicators = [ /operation.*timeout/i, /request.*timeout/i, /socket.*timeout/i, /connection.*timeout/i, /read.*timeout/i, /write.*timeout/i, /execution.*timeout/i, ]; // If it contains timeout and specific timeout indicators, it's probably real if (errorString.includes('timeout') && realTimeoutIndicators.some(pattern => pattern.test(errorString))) { return false; } return false; } /** * Get error statistics for monitoring */ static getErrorStats(): { classifications: Record<string, number>; commonPatterns: Array<{ pattern: string; count: number }>; } { // This would be implemented with actual error tracking // For now, return empty stats return { classifications: {}, commonPatterns: [], }; } } /** * Convenience function for creating standardized error responses */ export function createStandardizedError( error: Error | string, toolName: string, operation?: string, parameters?: Record<string, unknown> ) { return ErrorClassifier.createStandardizedErrorResponse(error, { toolName, operation, parameters, originalError: typeof error === 'string' ? new Error(error) : error, }); } /** * Convenience function for enhancing existing error responses */ export function enhanceExistingError( existingResponse: any, error: Error | string, toolName: string, operation?: string ) { return ErrorClassifier.enhanceErrorResponse(existingResponse, error, { toolName, operation, originalError: typeof error === 'string' ? new Error(error) : error, }); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/amittell/firewalla-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server