Files
daily-notification-plugin/ios/Plugin/DailyNotificationErrorCodes.swift
Matthew 3649e76c49 feat(ios): add error handling and integration tests
Implement comprehensive error handling and integration test suite:

Error Handling (Section 8):
- Add iOS-specific error codes to DailyNotificationErrorCodes:
  - NOTIFICATION_PERMISSION_DENIED
  - PENDING_NOTIFICATION_LIMIT_EXCEEDED
  - BG_TASK_NOT_REGISTERED
  - BG_TASK_EXECUTION_FAILED
  - BACKGROUND_REFRESH_DISABLED
- Add helper methods for iOS-specific error responses
- Enhance error handling in ReactivationManager:
  - Database errors handled gracefully (non-fatal)
  - Notification center errors handled gracefully (non-fatal)
  - Scheduling errors handled gracefully (non-fatal)
  - All errors logged, app continues normally
  - Partial results returned when operations fail
- Update plugin methods to use iOS-specific error codes:
  - getNotificationPermissionStatus uses NOTIFICATION_PERMISSION_DENIED

Integration Tests (Section 9.2):
- Add DailyNotificationRecoveryIntegrationTests:
  - Full recovery flow tests (cold start, termination)
  - Error handling tests (database, notification center, scheduling)
  - App stability tests (no crashes, concurrent operations)
  - Partial recovery tests
  - Timeout handling tests
- Test coverage:
  - 10 integration tests covering recovery scenarios
  - Error handling verification
  - App stability verification
  - Concurrent operation safety

Completes sections 8.1, 8.2, and 9.2 of iOS implementation checklist.
2025-12-09 02:46:13 -08:00

182 lines
5.4 KiB
Swift

/**
* DailyNotificationErrorCodes.swift
*
* Error code constants matching Android implementation
*
* @author Matthew Raymer
* @version 1.0.0
*/
import Foundation
/**
* Error code constants matching Android error handling
*
* These error codes must match Android's error response format:
* {
* "error": "error_code",
* "message": "Human-readable error message"
* }
*/
struct DailyNotificationErrorCodes {
// MARK: - Permission Errors
static let NOTIFICATIONS_DENIED = "notifications_denied"
static let BACKGROUND_REFRESH_DISABLED = "background_refresh_disabled"
static let PERMISSION_DENIED = "permission_denied"
// MARK: - iOS-Specific Error Codes
static let NOTIFICATION_PERMISSION_DENIED = "notification_permission_denied"
static let PENDING_NOTIFICATION_LIMIT_EXCEEDED = "pending_notification_limit_exceeded"
static let BG_TASK_NOT_REGISTERED = "bg_task_not_registered"
static let BG_TASK_EXECUTION_FAILED = "bg_task_execution_failed"
// MARK: - Configuration Errors
static let INVALID_TIME_FORMAT = "invalid_time_format"
static let INVALID_TIME_VALUES = "invalid_time_values"
static let CONFIGURATION_FAILED = "configuration_failed"
static let MISSING_REQUIRED_PARAMETER = "missing_required_parameter"
// MARK: - Scheduling Errors
static let SCHEDULING_FAILED = "scheduling_failed"
static let TASK_SCHEDULING_FAILED = "task_scheduling_failed"
static let NOTIFICATION_SCHEDULING_FAILED = "notification_scheduling_failed"
// MARK: - Storage Errors
static let STORAGE_ERROR = "storage_error"
static let DATABASE_ERROR = "database_error"
// MARK: - Network Errors (Phase 3)
static let NETWORK_ERROR = "network_error"
static let FETCH_FAILED = "fetch_failed"
static let TIMEOUT = "timeout"
// MARK: - System Errors
static let PLUGIN_NOT_INITIALIZED = "plugin_not_initialized"
static let INTERNAL_ERROR = "internal_error"
static let SYSTEM_ERROR = "system_error"
// MARK: - Helper Methods
/**
* Create error response dictionary
*
* @param code Error code
* @param message Human-readable error message
* @return Error response dictionary
*/
static func createErrorResponse(code: String, message: String) -> [String: Any] {
return [
"error": code,
"message": message
]
}
/**
* Create error response for missing parameter
*
* @param parameter Parameter name
* @return Error response dictionary
*/
static func missingParameter(_ parameter: String) -> [String: Any] {
return createErrorResponse(
code: MISSING_REQUIRED_PARAMETER,
message: "Missing required parameter: \(parameter)"
)
}
/**
* Create error response for invalid time format
*
* @return Error response dictionary
*/
static func invalidTimeFormat() -> [String: Any] {
return createErrorResponse(
code: INVALID_TIME_FORMAT,
message: "Invalid time format. Use HH:mm"
)
}
/**
* Create error response for notifications denied
*
* @return Error response dictionary
*/
static func notificationsDenied() -> [String: Any] {
return createErrorResponse(
code: NOTIFICATIONS_DENIED,
message: "Notification permissions denied"
)
}
// MARK: - iOS-Specific Error Helpers
/**
* Create error response for notification permission denied
*
* @return Error response dictionary
*/
static func notificationPermissionDenied() -> [String: Any] {
return createErrorResponse(
code: NOTIFICATION_PERMISSION_DENIED,
message: "Notification permission denied. User must grant permission in Settings."
)
}
/**
* Create error response for pending notification limit exceeded
*
* @return Error response dictionary
*/
static func pendingNotificationLimitExceeded() -> [String: Any] {
return createErrorResponse(
code: PENDING_NOTIFICATION_LIMIT_EXCEEDED,
message: "Pending notification limit exceeded. iOS allows maximum 64 pending notifications."
)
}
/**
* Create error response for background task not registered
*
* @return Error response dictionary
*/
static func bgTaskNotRegistered() -> [String: Any] {
return createErrorResponse(
code: BG_TASK_NOT_REGISTERED,
message: "Background task not registered. Ensure BGTaskScheduler is properly configured."
)
}
/**
* Create error response for background task execution failed
*
* @return Error response dictionary
*/
static func bgTaskExecutionFailed() -> [String: Any] {
return createErrorResponse(
code: BG_TASK_EXECUTION_FAILED,
message: "Background task execution failed. Check Background App Refresh settings."
)
}
/**
* Create error response for background refresh disabled
*
* @return Error response dictionary
*/
static func backgroundRefreshDisabled() -> [String: Any] {
return createErrorResponse(
code: BACKGROUND_REFRESH_DISABLED,
message: "Background App Refresh is disabled. Enable it in Settings > General > Background App Refresh."
)
}
}