# Error Handling

### Exit Codes

| Code | Meaning |
|------|---------|
| 0 | Success |
| 1 | General error |
| 2 | Authentication error |
| 3 | Authorization error (missing permissions) |
| 4 | Not found (user, number, policy) |
| 5 | Validation error (invalid input) |
| 6 | Rate limit exceeded |
| 7 | Configuration error |

### Error Messages

All errors include:
- Clear description of what went wrong
- Suggested remediation steps
- `--verbose` flag hint for more details

**Example:**
```
Error: User not found: john.doe@contoso.com

  The specified user was not found in the tenant directory.

  Suggestions:
  - Verify the UPN is correct
  - Check if the user exists: teams-phone users search "john"
  - Ensure you're connected to the correct tenant

  Use --verbose for detailed error information.
```

### Graph API Error Mapping

The CLI maps Graph API HTTP status codes to CLI exit codes as follows:

| Graph API Status | CLI Exit Code | Error Type | Notes |
|------------------|---------------|------------|-------|
| `200`, `202`, `204` | 0 | Success | Operation completed successfully |
| `400` | 5 | Validation error | Invalid input parameters |
| `401` | 2 | Authentication error | Token missing, expired, or invalid |
| `403` | 3 | Authorization error | Missing required permissions |
| `404` | 4 | Not found | User, number, policy, or location not found |
| `405` | 1 | General error | Method not allowed (e.g., beta endpoint called via v1.0) |
| `409` | 5 | Validation error | Conflict (e.g., number already assigned) |
| `424` | 1 | General error | Failed dependency (batch operation) |
| `429` | 6 | Rate limit exceeded | Throttling limit exceeded |
| `500`, `502`, `503`, `504` | 1 | General error | Server error (will retry with backoff) |
| Network errors | 1 | General error | Connection timeout, DNS failure, etc. |

**Retry Strategy:**
- `429` (Rate limit): Retry with exponential backoff (3 attempts)
- `503` (Service unavailable): Retry with exponential backoff (3 attempts)
- All other errors: No automatic retry

### Cache Fallback (Read-only)

- If Graph is unavailable or throttled after retries (3 retries with exponential backoff), read-only commands may return cached data with a visible stale indicator and age
- Fallback data must be less than 1 hour old (regardless of normal TTL settings: users 5min, numbers 5min, policies 10min)
- If no valid fallback data exists, command fails with exit code 6 and retry guidance
- `--no-cache` disables fallback and surfaces the underlying error immediately
- Write commands (assign, unassign, reserve, policy assign, etc.) never fall back to cached data

---

