Expert error handling decisions for iOS/tvOS: when to use throws vs Result, error type design trade-offs, recovery strategy selection, and user-facing error presentation patterns. Use when designing error hierarchies, implementing retry logic, or deciding how to surface errors to users. Trigger keywords: Error, throws, Result, LocalizedError, retry, recovery, error presentation, do-catch, try, error handling, failure
View on GitHubKaakati/rails-enterprise-dev
reactree-ios-dev
January 25, 2026
Select agents to install to:
npx add-skill https://github.com/Kaakati/rails-enterprise-dev/blob/main/plugins/reactree-ios-dev/skills/error-handling-patterns/SKILL.md -a claude-code --skill error-handling-patternsInstallation paths:
.claude/skills/error-handling-patterns/# Error Handling Patterns — Expert Decisions
Expert decision frameworks for error handling choices. Claude knows Swift error syntax — this skill provides judgment calls for error type design and recovery strategies.
---
## Decision Trees
### throws vs Result
```
Does the caller need to handle success/failure explicitly?
├─ YES (caller must acknowledge failure)
│ └─ Is the failure common and expected?
│ ├─ YES → Result<T, E> (explicit handling, no try/catch)
│ └─ NO → throws (exceptional case)
│
└─ NO (caller can ignore failure)
└─ Use throws with try? at call site
```
**When Result wins**: Parsing, validation, operations where failure is common and needs explicit handling. Forces exhaustive switch.
**When throws wins**: Network calls, file operations where failure is exceptional. Cleaner syntax with async/await.
### Error Type Granularity
```
How specific should error types be?
├─ API boundary (framework, library)
│ └─ Coarse-grained domain errors
│ enum NetworkError: Error { case timeout, serverError, ... }
│
├─ Internal module
│ └─ Fine-grained for actionable handling
│ enum PaymentError: Error {
│ case cardDeclined(reason: String)
│ case insufficientFunds(balance: Decimal, required: Decimal)
│ }
│
└─ User-facing
└─ LocalizedError with user-friendly messages
var errorDescription: String? { "Payment failed" }
```
**The trap**: Too many error types that no one handles differently. If every case has the same handler, collapse them.
### Recovery Strategy Selection
```
Is the error transient (network, timeout)?
├─ YES → Is it idempotent?
│ ├─ YES → Retry with exponential backoff
│ └─ NO → Retry cautiously or fail
│
└─ NO → Is recovery possible?
├─ YES → Can user fix it?
│ ├─ YES → Show actionable error UI
│ └─ NO → Auto-recover or fallback value
│
└─ NO → Log and show generic error
```
### Error Presentation Selection
```
How critical is the failure?
├─ Critical (can't continue)
│ └─ F