Skip to content

One DeviceFault classifier, four thin translations (T-021) - #31

Merged
Skeyelab merged 1 commit into
mainfrom
feat/t-021-device-fault
Jul 17, 2026
Merged

Skeyelab merged 1 commit into
mainfrom
feat/t-021-device-fault

Conversation

@Skeyelab

Copy link
Copy Markdown
Member

"What kind of failure was that?" was hand-rolled at four call sites, each re-deriving the same
three-way decision and leaking KitchenSyncClientError/DecodingError into every view model.

  • New pure Networking/DeviceFault.swift — classify(Error) -> DeviceFault (undecodable /
    notFound / rejected(Int) / unreachable), tested directly at its interface (5 cases, test-first).
  • refreshStatus, loadConfig, apply (DeviceDetailViewModel) and refreshAll (DeviceListViewModel)
    translate one fault into their local enum; none re-inspect the transport error types.
  • Distinct signals preserved (undecodable / old-firmware / unreachable stay separate — T-009/010/016/018).
  • Full suite green: 148 tests, 0 failures.

https://claude.ai/code/session_01F7YsQgso3KNpeXbP5vNVj6

…(T-021)

"What kind of failure was that?" was hand-rolled at four call sites, each re-deriving the same
answered-and-read / answered-but-undecodable / didn't-answer decision from an identical
`catch is DecodingError`, and leaking `KitchenSyncClientError`/`DecodingError` across the seam.

Add a pure `DeviceFault.classify(Error) -> DeviceFault` (undecodable / notFound / rejected(Int)
/ unreachable), tested directly at its interface (DeviceFaultTests, 5 cases, test-first). The
four sites — refreshStatus, loadConfig, apply, refreshAll — now translate one fault into their
own presentation enum; none re-inspect the transport error types. Distinct signals preserved
(T-009/T-010/T-016/T-018 not re-collapsed). Full suite green: 148 tests, 0 failures.

Claude-Session: https://claude.ai/code/session_01F7YsQgso3KNpeXbP5vNVj6
@Skeyelab
Skeyelab enabled auto-merge (squash) July 17, 2026 05:15
@Skeyelab
Skeyelab merged commit 71b956b into main Jul 17, 2026
Skeyelab added a commit that referenced this pull request Aug 23, 2026
…(T-021) (#31)

"What kind of failure was that?" was hand-rolled at four call sites, each re-deriving the same
answered-and-read / answered-but-undecodable / didn't-answer decision from an identical
`catch is DecodingError`, and leaking `KitchenSyncClientError`/`DecodingError` across the seam.

Add a pure `DeviceFault.classify(Error) -> DeviceFault` (undecodable / notFound / rejected(Int)
/ unreachable), tested directly at its interface (DeviceFaultTests, 5 cases, test-first). The
four sites — refreshStatus, loadConfig, apply, refreshAll — now translate one fault into their
own presentation enum; none re-inspect the transport error types. Distinct signals preserved
(T-009/T-010/T-016/T-018 not re-collapsed). Full suite green: 148 tests, 0 failures.

Claude-Session: https://claude.ai/code/session_01F7YsQgso3KNpeXbP5vNVj6

Co-authored-by: Eric Dahl <edahl@nd.edu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants