Overview › Error Handling & Logging

Error Handling & Logging

30+ print() in production paths; no centralized logger; OSLog/swift-log not adopted.

6 findings in this category · iOS
68
SCORE

Summary

Logging is informal: print() in production widget + analytics utilities, no os.Logger adoption visible in the scan. No central error model. Crashlytics integration unclear from the iOS scan; verify it's wired into application(_:didFinishLaunchingWithOptions:).

Apple-recommended logging stack

ToolUseStatus
os.Logger (OSLog)Structured, categorized logging w/ privacy controlsNOT ADOPTED
os_signpost / OSSignposterPerformance traces in InstrumentsNOT ADOPTED
CrashlyticsCrash + non-fatal reportingVERIFY
MetricKitHangs, energy, disk, scrolling metrics from real usersNOT FOUND
print()Quick debugPRESENT in production
NSLogLegacyAudit and remove

Recommended pattern

import os

extension Logger {
  static let subsystem = Bundle.main.bundleIdentifier ?? "com.costco.costco"
  static let auth = Logger(subsystem: subsystem, category: "auth")
  static let cart = Logger(subsystem: subsystem, category: "cart")
  static let network = Logger(subsystem: subsystem, category: "network")
  static let pdp = Logger(subsystem: subsystem, category: "pdp")
}

// Usage — privacy-aware interpolation
Logger.auth.debug("OIDC challenge created for member \(memberId, privacy: .private)")
Logger.cart.error("Cart sync failed: \(error.localizedDescription, privacy: .public)")

MetricKit hangs for the iOS analog of ANRs

Android has ANRs; iOS has hangs. MetricKit's MXHangDiagnostic reports them. Adopt MetricKit + push payloads to Crashlytics as non-fatals.

Findings

""
HIGH

30+ print() in production paths

DMCWidgetExtension, OffersTestUtilities (used in production widget), various analytics helpers all print(). print() goes to console regardless of build config, may leak PII.
Recommendation: Adopt os.Logger with categorized signposts; mark sensitive interpolations with privacy: .private; gate raw print by #if DEBUG.
MEDIUM

No central typed error model

Without a sealed AppError enum, error handling drifts per feature.
Recommendation: Define AppError in Core; require all public APIs to throw or return Result<T, AppError>.
MEDIUM

Crashlytics integration verification

Confirm Crashlytics is wired with proper symbol upload + dSYM handling.
Recommendation: Verify Build Phase script runs Crashlytics dSYM upload; ensure user identifier is not set to PII.

Findings in this category

6 shown
Costco iOS · Code Review Report · Generated 2026-05-07 · 88 machine-curated findings