From e9e3e9da1f88c06348f6e4ce798d9da688445a39 Mon Sep 17 00:00:00 2001 From: Daniel Arantes Loverde Date: Fri, 31 Jul 2026 14:05:29 -0300 Subject: [PATCH] [app-attest-env] Log the actual error behind guest-session App Attest failures Guest session handshake fails silently after the challenge step - no console output, just a generic "could not load" message in the UI. DCAppAttestService errors (generateKey/attestKey/generateAssertion) propagate up uncaught by anything that logs them. Add explicit logging at each step so the real thrown error is visible instead of debugging blind. --- .../Services/GuestSessionService.swift | 26 ++++++++++++++++--- .../Views/Main/PublicLocationPickerView.swift | 1 + 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Sources/PediFoods/Services/GuestSessionService.swift b/Sources/PediFoods/Services/GuestSessionService.swift index 869c3ed..9206983 100644 --- a/Sources/PediFoods/Services/GuestSessionService.swift +++ b/Sources/PediFoods/Services/GuestSessionService.swift @@ -93,6 +93,7 @@ actor GuestSessionService { #if os(iOS) private func refreshTokenWithAppAttest() async throws -> String { + print("[GuestSessionService] DCAppAttestService.isSupported = \(DCAppAttestService.shared.isSupported), existingKeyId = \(store.appAttestKeyId ?? "nil")") guard DCAppAttestService.shared.isSupported else { // Simulator can never support App Attest (hardware limitation, // not environment-specific) — server has its own documented @@ -141,9 +142,22 @@ actor GuestSessionService { } private func handshakeWithFreshAttestation(challenge: String) async throws -> String { - let keyId = try await DCAppAttestService.shared.generateKey() + let keyId: String + do { + keyId = try await DCAppAttestService.shared.generateKey() + } catch { + print("[GuestSessionService] generateKey failed: \(error)") + throw error + } + let clientDataHash = Data(SHA256.hash(data: Data(challenge.utf8))) - let attestationObject = try await DCAppAttestService.shared.attestKey(keyId, clientDataHash: clientDataHash) + let attestationObject: Data + do { + attestationObject = try await DCAppAttestService.shared.attestKey(keyId, clientDataHash: clientDataHash) + } catch { + print("[GuestSessionService] attestKey failed: \(error)") + throw error + } let payload = GuestSessionAttestPayload( platform: "ios", @@ -175,7 +189,13 @@ actor GuestSessionService { private func handshakeWithAssertion(keyId: String, challenge: String) async throws -> String { let clientDataHash = Data(SHA256.hash(data: Data(challenge.utf8))) - let assertionObject = try await DCAppAttestService.shared.generateAssertion(keyId, clientDataHash: clientDataHash) + let assertionObject: Data + do { + assertionObject = try await DCAppAttestService.shared.generateAssertion(keyId, clientDataHash: clientDataHash) + } catch { + print("[GuestSessionService] generateAssertion failed: \(error)") + throw error + } let payload = GuestSessionAttestPayload( platform: "ios", diff --git a/Sources/PediFoods/Views/Main/PublicLocationPickerView.swift b/Sources/PediFoods/Views/Main/PublicLocationPickerView.swift index 085b911..f5263e1 100644 --- a/Sources/PediFoods/Views/Main/PublicLocationPickerView.swift +++ b/Sources/PediFoods/Views/Main/PublicLocationPickerView.swift @@ -161,6 +161,7 @@ struct PublicLocationPickerView: View { errorMessage = "Nenhum estado disponível no momento." } } catch { + print("[PublicLocationPickerView] loadLocations failed: \(error)") errorMessage = "Não foi possível carregar. Tente novamente." } isLoading = false