When a metric lacks authorization (.sharingDenied), HealthKit queries may succeed but return 0 data, making them appear as complete/successful despite lacking access. This causes the 'silent failure' issue. Fix: Check authorization status before attempting queries. If .sharingDenied, immediately return TypeCount with quality .unauthorized instead of querying. This ensures metrics without permission are properly marked as failed. The existing error handling still catches authorization errors thrown during queries (for cases where status check doesn't prevent the error). Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@@ -225,6 +225,17 @@ final class HealthKitService {
|
||
| 225 | 225 |
return tc |
| 226 | 226 |
} |
| 227 | 227 |
|
| 228 |
+ // Check authorization status before querying — if denied, fail immediately |
|
| 229 |
+ // (HealthKit queries for denied types might succeed with 0 data, appearing complete) |
|
| 230 |
+ if store.authorizationStatus(for: sampleType) == .sharingDenied {
|
|
| 231 |
+ return TypeCount( |
|
| 232 |
+ typeIdentifier: monitoredType.id, |
|
| 233 |
+ displayName: monitoredType.displayName, |
|
| 234 |
+ count: -1, |
|
| 235 |
+ quality: SnapshotQuality.unauthorized |
|
| 236 |
+ ) |
|
| 237 |
+ } |
|
| 238 |
+ |
|
| 228 | 239 |
// 15s budget covers distribution + earliestDate + latestDate combined — not 15s each. |
| 229 | 240 |
do {
|
| 230 | 241 |
return try await withTimeout(seconds: Self.perTypeTimeoutSeconds) {
|