1.2.0: report non-fatal errors to Crashlytics across key error paths
CrashlyticsService was wired only for the is_premium custom key. Route the swallowed errors in the main catch blocks through CrashlyticsService.record with a context tag, so non-fatals show up in Firebase (StoreKit load/purchase/ restore, calendar access/create/update/delete, reset-all-data, onboarding save). Debug prints kept. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BkanrydYtrme8wipTzWssG
This commit is contained in:
@@ -12,6 +12,7 @@ final class CalendarService {
|
|||||||
do {
|
do {
|
||||||
return try await eventStore.requestFullAccessToEvents()
|
return try await eventStore.requestFullAccessToEvents()
|
||||||
} catch {
|
} catch {
|
||||||
|
CrashlyticsService.record(error, context: "calendar_access")
|
||||||
print("Calendar access error: \(error)")
|
print("Calendar access error: \(error)")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -55,6 +56,7 @@ final class CalendarService {
|
|||||||
try eventStore.save(event, span: .thisEvent)
|
try eventStore.save(event, span: .thisEvent)
|
||||||
return event.eventIdentifier
|
return event.eventIdentifier
|
||||||
} catch {
|
} catch {
|
||||||
|
CrashlyticsService.record(error, context: "calendar_create")
|
||||||
print("Error saving event: \(error)")
|
print("Error saving event: \(error)")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -99,6 +101,7 @@ final class CalendarService {
|
|||||||
try eventStore.save(event, span: .thisEvent)
|
try eventStore.save(event, span: .thisEvent)
|
||||||
return event.eventIdentifier
|
return event.eventIdentifier
|
||||||
} catch {
|
} catch {
|
||||||
|
CrashlyticsService.record(error, context: "calendar_update")
|
||||||
print("Error updating event: \(error)")
|
print("Error updating event: \(error)")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -109,6 +112,7 @@ final class CalendarService {
|
|||||||
do {
|
do {
|
||||||
try eventStore.remove(event, span: .thisEvent)
|
try eventStore.remove(event, span: .thisEvent)
|
||||||
} catch {
|
} catch {
|
||||||
|
CrashlyticsService.record(error, context: "calendar_delete")
|
||||||
print("Error deleting event: \(error)")
|
print("Error deleting event: \(error)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ final class StoreManager: ObservableObject {
|
|||||||
productLoadState = .timedOut
|
productLoadState = .timedOut
|
||||||
} else {
|
} else {
|
||||||
productLoadState = .failed
|
productLoadState = .failed
|
||||||
|
CrashlyticsService.record(error, context: "load_products")
|
||||||
}
|
}
|
||||||
print("Failed to load products: \(error)")
|
print("Failed to load products: \(error)")
|
||||||
}
|
}
|
||||||
@@ -93,6 +94,7 @@ final class StoreManager: ObservableObject {
|
|||||||
return .failed
|
return .failed
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
CrashlyticsService.record(error, context: "purchase")
|
||||||
print("Purchase failed: \(error)")
|
print("Purchase failed: \(error)")
|
||||||
return .failed
|
return .failed
|
||||||
}
|
}
|
||||||
@@ -110,6 +112,7 @@ final class StoreManager: ObservableObject {
|
|||||||
AnalyticsService.logPremiumRestored()
|
AnalyticsService.logPremiumRestored()
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
CrashlyticsService.record(error, context: "restore")
|
||||||
print("Restore failed: \(error)")
|
print("Restore failed: \(error)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ final class OnboardingViewModel: ObservableObject {
|
|||||||
UserDefaults.standard.set(true, forKey: Self.pendingPremiumPromptKey)
|
UserDefaults.standard.set(true, forKey: Self.pendingPremiumPromptKey)
|
||||||
return true
|
return true
|
||||||
} catch {
|
} catch {
|
||||||
|
CrashlyticsService.record(error, context: "onboarding_save")
|
||||||
print("Onboarding save failed: \(error)")
|
print("Onboarding save failed: \(error)")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,12 +97,14 @@ final class SettingsViewModel: ObservableObject {
|
|||||||
UserDefaults.standard.set(false, forKey: OnboardingViewModel.pendingPremiumPromptKey)
|
UserDefaults.standard.set(false, forKey: OnboardingViewModel.pendingPremiumPromptKey)
|
||||||
try context.save()
|
try context.save()
|
||||||
} catch {
|
} catch {
|
||||||
|
CrashlyticsService.record(error, context: "reset_all_data")
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
print("Failed to complete reset all data: \(error)")
|
print("Failed to complete reset all data: \(error)")
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
CrashlyticsService.record(error, context: "reset_all_data_start")
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
print("Failed to start reset all data: \(error)")
|
print("Failed to start reset all data: \(error)")
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user