mirror of
https://github.com/awizemann/scarf.git
synced 2026-05-10 18:44:45 +00:00
3da3d3ce5e
Bundled because the fixes are coherent — they all add the same mechanism (`lastError` + `os.Logger`) to the same model. A.3 — Distinguish "no servers" from "Keychain unreachable": - `RootModel.connect(to:)` previously used `try?` on `keyStore.load(for:)`. A biometric cancel or device-locked Keychain read returned nil → the app dropped the user into fresh onboarding, destroying the existing server's host/user/port. Now we catch the throw, log via os.Logger, set `lastError`, and stay on `.serverList`. The user sees a banner + Dismiss button instead of being kicked back to onboarding. - `RootModel.load()` now logs the corrupted-blob path via os.Logger and sets `lastError` before falling through to onboarding (recovery is necessary, but the user gets context now). A.4 — Surface delete failures in `forget()` and `disconnect()`: - Both used `try?` on every store delete. On partial failure the in-memory dict was wiped while orphan Keychain entries lingered. Now each delete is `do/catch` with logging, failures collected into `lastError`. The in-memory state is reloaded from disk so it tracks what's actually persisted (covers the partial-failure case). ServerListView gains an inline error banner above the list that reads `model.lastError`, with a Dismiss button calling `clearLastError()`. Verified: iOS build succeeds. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>