Skip to main content
Glama

Peekaboo MCP

by steipete
error-handling-guide.mdβ€’7.58 kB
# Peekaboo Error Handling Guide This guide describes the unified error handling system in PeekabooCore, designed to provide consistent, user-friendly error messages across all services. ## Overview The error handling system consists of three main components: 1. **Standardized Errors** - Consistent error types and codes 2. **Error Formatting** - Unified presentation for CLI, JSON, and logs 3. **Error Recovery** - Automatic retry and graceful degradation ## Error Types ### Standard Error Codes All errors in Peekaboo use standardized error codes for consistency: ```swift // Permission errors case screenRecordingPermissionDenied = "PERMISSION_DENIED_SCREEN_RECORDING" case accessibilityPermissionDenied = "PERMISSION_DENIED_ACCESSIBILITY" // Not found errors case applicationNotFound = "APP_NOT_FOUND" case windowNotFound = "WINDOW_NOT_FOUND" case elementNotFound = "ELEMENT_NOT_FOUND" // Operation errors case captureFailed = "CAPTURE_FAILED" case interactionFailed = "INTERACTION_FAILED" case timeout = "TIMEOUT" ``` ### Error Categories Errors are grouped into categories: - **Permission**: Access control issues - **Not Found**: Missing resources - **Operation**: Execution failures - **Validation**: Input errors - **System**: Infrastructure issues - **AI**: AI provider problems ## Using the Error System ### Creating Errors Use the predefined error types for consistency: ```swift // Permission errors throw PermissionError.screenRecording() throw PermissionError.accessibility() // Not found errors throw NotFoundError.application("Safari") throw NotFoundError.window(app: "Finder", index: 2) throw NotFoundError.element("Submit button") // Operation errors throw OperationError.captureFailed(reason: "Display disconnected") throw OperationError.timeout(operation: "screenshot", duration: 30) // Validation errors throw ValidationError.invalidInput(field: "coordinates", reason: "Outside screen bounds") throw ValidationError.ambiguousAppIdentifier("Safari", matches: ["Safari", "Safari Technology Preview"]) ``` ### Formatting Errors Use `ErrorFormatter` for consistent presentation: ```swift // For CLI output let message = ErrorFormatter.formatForCLI(error, verbose: true) // For JSON responses let json = ErrorFormatter.formatForJSON(error) // For logging let logMessage = ErrorFormatter.formatForLog(error) // For multiple errors let summary = ErrorFormatter.formatMultipleErrors(errors) ``` ## Error Recovery ### Retry Policies Configure automatic retry behavior: ```swift // Use standard retry policy (3 attempts, exponential backoff) let result = try await RetryHandler.withRetry { try await captureScreen() } // Custom retry policy let policy = RetryPolicy( maxAttempts: 5, initialDelay: 0.1, delayMultiplier: 2.0, retryableErrors: [.timeout, .captureFailed] ) let result = try await RetryHandler.withRetry(policy: policy) { try await performOperation() } ``` ### Recovery Suggestions Errors include recovery suggestions: ```swift let error = PermissionError.screenRecording() if let suggestion = error.recoverySuggestion { print("Suggestion: \(suggestion)") // Output: "Grant Screen Recording permission in System Settings" } ``` ### Graceful Degradation Handle partial failures: ```swift let options = DegradationOptions( allowPartialResults: true, fallbackToDefaults: true, skipNonCritical: true ) // Operations can return degraded results let result = DegradedResult( value: partialData, errors: [minorError], warnings: ["Some features unavailable"], isPartial: true ) ``` ## Service Integration ### Example: ScreenCaptureService ```swift public func captureScreen(displayIndex: Int? = nil) async throws -> CaptureResult { // Check permissions guard hasScreenRecordingPermission() else { throw PermissionError.screenRecording() } // Validate input if let index = displayIndex, index < 0 || index >= screenCount { throw ValidationError.invalidInput( field: "displayIndex", reason: "Must be between 0 and \(screenCount - 1)" ) } // Perform capture with retry return try await RetryHandler.withRetry(policy: .standard) { guard let image = performCapture() else { throw OperationError.captureFailed( reason: "Unable to capture display" ) } return CaptureResult(image: image) } } ``` ## CLI Integration ### Error Output The CLI automatically formats errors based on output mode: ```bash # Normal mode - user-friendly message $ peekaboo capture Error: Screen Recording permission is required. Please grant permission in System Settings > Privacy & Security > Screen Recording. Suggestion: Grant Screen Recording permission in System Settings # Verbose mode - includes context $ peekaboo capture --verbose Error: Screen Recording permission is required... Suggestion: Grant Screen Recording permission in System Settings Context: permission: screen_recording # JSON mode - structured output $ peekaboo capture --json-output { "success": false, "error": { "error_code": "PERMISSION_DENIED_SCREEN_RECORDING", "message": "Screen Recording permission is required...", "recovery_suggestion": "Grant Screen Recording permission in System Settings", "context": { "permission": "screen_recording" } } } ``` ## Best Practices ### 1. Use Standardized Errors Always use the predefined error types instead of creating custom errors: ```swift // βœ… Good throw NotFoundError.application("TextEdit") // ❌ Avoid throw NSError(domain: "PeekabooError", code: 404, userInfo: nil) ``` ### 2. Provide Context Include relevant context in errors: ```swift throw ValidationError.invalidCoordinates(x: 5000, y: 3000) // Error includes the invalid coordinates in context ``` ### 3. Use Appropriate Retry Policies Choose retry policies based on operation type: ```swift // Network operations - aggressive retry RetryPolicy.aggressive // User interactions - conservative retry RetryPolicy.conservative // Critical operations - no retry RetryPolicy.noRetry ``` ### 4. Handle Degraded Results Design services to continue with partial data when appropriate: ```swift // Allow partial window list if some windows fail let windows = await collectWindows(options: .lenient) if windows.isPartial { logger.warning("Some windows could not be accessed") } ``` ## Migration Guide To migrate existing error handling: 1. Replace custom errors with standardized types 2. Update error formatting to use `ErrorFormatter` 3. Add retry logic where appropriate 4. Implement recovery suggestions Example migration: ```swift // Before throw NSError(domain: "Peekaboo", code: 1, userInfo: [ NSLocalizedDescriptionKey: "App not found" ]) // After throw NotFoundError.application(appName) ``` ## Testing Errors Test error handling comprehensively: ```swift @Test func testPermissionError() async throws { let error = PermissionError.screenRecording() #expect(error.code == .screenRecordingPermissionDenied) #expect(error.userMessage.contains("Screen Recording")) #expect(error.recoverySuggestion \!= nil) let json = ErrorFormatter.formatForJSON(error) #expect(json["error_code"] as? String == "PERMISSION_DENIED_SCREEN_RECORDING") } ``` ## Future Enhancements Planned improvements: - Localization support for error messages - Error analytics and reporting - Advanced recovery strategies - Error aggregation for batch operations EOF < /dev/null

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/steipete/Peekaboo'

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