Back to Skills

error-handling-patterns

verified

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 GitHub

Marketplace

manifest-marketplace

Kaakati/rails-enterprise-dev

Plugin

reactree-ios-dev

development

Repository

Kaakati/rails-enterprise-dev
2stars

plugins/reactree-ios-dev/skills/error-handling-patterns/SKILL.md

Last Verified

January 25, 2026

Install Skill

Select agents to install to:

Scope:
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-patterns

Installation paths:

Claude
.claude/skills/error-handling-patterns/
Powered by add-skill CLI

Instructions

# 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

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
9114 chars