Error Monitoring Generator
Generates a production-ready error monitoring infrastructure with protocol-based architecture for easy provider swapping.
When This Skill Activates
- User asks to "add crash reporting" or "error monitoring"
- User mentions "Sentry", "Crashlytics", or "crash analytics"
- User wants to "track errors in production"
- User asks about "debugging production issues"
Pre-Generation Checks (CRITICAL)
1. Project Context Detection
Before generating, ALWAYS check:
bash# Check for existing crash reporting rg -l "Sentry|Crashlytics|CrashReporter" --type swift # Check Package.swift for existing SDKs cat Package.swift | grep -i "sentry\|firebase\|crashlytics" # Check for existing error handling patterns rg "captureError|recordError|logError" --type swift | head -5
2. Conflict Detection
If existing crash reporting found:
- Ask: Replace, wrap existing, or create parallel system?
Configuration Questions
Ask user via AskUserQuestion:
-
Initial provider?
- Sentry (recommended for indie devs)
- Firebase Crashlytics (if already using Firebase)
- None (set up infrastructure only)
-
Include breadcrumbs?
- Yes (track navigation, user actions)
- No (errors only)
-
Include user context?
- Yes (anonymized user ID, app state)
- No (minimal data collection)
Generation Process
Step 1: Create Core Files
Always generate:
Sources/ErrorMonitoring/ ├── ErrorMonitoringService.swift # Protocol ├── ErrorContext.swift # Breadcrumbs, user info └── NoOpErrorMonitoring.swift # Testing/privacy
Based on provider selection:
Sources/ErrorMonitoring/Providers/ ├── SentryErrorMonitoring.swift # If Sentry selected └── CrashlyticsErrorMonitoring.swift # If Crashlytics selected
Step 2: Read Templates
Read templates from this skill:
templates/ErrorMonitoringService.swifttemplates/ErrorContext.swifttemplates/NoOpErrorMonitoring.swifttemplates/SentryErrorMonitoring.swift(if selected)templates/CrashlyticsErrorMonitoring.swift(if selected)
Step 3: Customize for Project
Adapt templates to match:
- Project naming conventions
- Existing error types
- Bundle identifier for Sentry DSN
Step 4: Integration
In App.swift:
swiftimport SwiftUI @main struct MyApp: App { init() { // Configure error monitoring ErrorMonitoring.shared.configure() } var body: some Scene { WindowGroup { ContentView() .environment(\.errorMonitoring, ErrorMonitoring.shared.service) } } }
Capturing errors:
swiftdo { try await riskyOperation() } catch { ErrorMonitoring.shared.service.captureError(error) }
Adding breadcrumbs:
swiftErrorMonitoring.shared.service.addBreadcrumb( Breadcrumb(category: "navigation", message: "Opened settings") )
Provider Setup
Sentry
- Create account at sentry.io
- Create project for iOS/macOS
- Get DSN from Project Settings > Client Keys
- Add to Package.swift:
swift.package(url: "https://github.com/getsentry/sentry-cocoa", from: "8.0.0")
Firebase Crashlytics
- Add Firebase to your project via console.firebase.google.com
- Download GoogleService-Info.plist
- Add Firebase SDK via SPM or CocoaPods
- Enable Crashlytics in Firebase console
Generated Code Patterns
Protocol (Stable Interface)
swiftprotocol ErrorMonitoringService: Sendable { func configure() func captureError(_ error: Error, context: ErrorContext?) func captureMessage(_ message: String, level: ErrorLevel) func addBreadcrumb(_ breadcrumb: Breadcrumb) func setUser(_ user: MonitoringUser?) func reset() }
Swapping Providers
swift// In ErrorMonitoring.swift final class ErrorMonitoring { static let shared = ErrorMonitoring() // Change this ONE line to swap providers: let service: ErrorMonitoringService = SentryErrorMonitoring() // let service: ErrorMonitoringService = CrashlyticsErrorMonitoring() // let service: ErrorMonitoringService = NoOpErrorMonitoring() }
Breadcrumb Tracking
swift// Automatic navigation breadcrumbs struct ContentView: View { @Environment(\.errorMonitoring) var errorMonitoring var body: some View { Button("Open Details") { errorMonitoring.addBreadcrumb( Breadcrumb(category: "ui", message: "Tapped details button") ) showDetails = true } } }
Verification Checklist
After generation, verify:
- App compiles without errors
- Provider SDK added (if applicable)
- DSN/config set correctly
- Test error appears in dashboard
- Breadcrumbs captured correctly
- User context (if enabled) shows in reports
- NoOp mode works for debug/testing
Privacy Considerations
GDPR Compliance
- Use
NoOpErrorMonitoringfor EU users who opt out - Don't capture PII in error messages
- Anonymize user IDs
App Store Guidelines
- Disclose crash reporting in privacy policy
- Use App Tracking Transparency if combining with analytics
- Don't capture unnecessary device identifiers
Privacy Manifest (iOS 17+)
Add to PrivacyInfo.xcprivacy if using Sentry/Crashlytics:
xml<key>NSPrivacyCollectedDataTypes</key> <array> <dict> <key>NSPrivacyCollectedDataType</key> <string>NSPrivacyCollectedDataTypeCrashData</string> <key>NSPrivacyCollectedDataTypeLinked</key> <false/> <key>NSPrivacyCollectedDataTypeTracking</key> <false/> <key>NSPrivacyCollectedDataTypePurposes</key> <array> <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string> </array> </dict> </array>
Common Customizations
Custom Error Types
swiftenum AppError: Error { case networkFailure(URLError) case decodingFailure(DecodingError) case authenticationRequired var context: ErrorContext { ErrorContext( tags: ["error_type": String(describing: self)], extra: ["recoverable": isRecoverable] ) } } // Capture with context errorMonitoring.captureError(error, context: error.context)
Performance Monitoring
swift// Sentry supports performance monitoring let transaction = SentrySDK.startTransaction(name: "Load Data", operation: "http") defer { transaction.finish() } let data = try await fetchData()
Release Tracking
swift// Include version info SentrySDK.start { options in options.dsn = "YOUR_DSN" options.releaseName = "\(Bundle.main.appVersion)-\(Bundle.main.buildNumber)" }
Troubleshooting
Errors Not Appearing in Dashboard
- Check DSN is correct and not expired
- Verify network connectivity
- Check debug mode isn't suppressing uploads
- Look for SDK initialization errors in console
Symbolication Not Working
- Upload dSYMs to Sentry/Firebase
- Enable "Upload Debug Symbols" build phase
- Check build settings include debug info
High Volume / Costs
- Filter common/expected errors
- Sample errors (e.g., capture 10%)
- Group similar errors
Related Skills
analytics-setup- Often combined with error monitoringlogging-setup- Use Logger for debug, error monitoring for production

