# Error Handling Strategy — API TC Design

**Purpose:** Define technique routing and TC generation rules for HTTP error codes in API tests. Single source of truth for "which technique applies to which error class."

**Used by:** `/tas-apitest-plan` Phase 2 (Design) — Step: Error Coverage Design

---

## Error Code → Technique Routing

| HTTP Status | Error Class | Technique | TC count | Notes |
|---|---|---|---|---|
| **400** | Bad Request — field validation | EP per field constraint | 1 per constraint | Missing required, wrong type, format violation |
| **401** | Unauthorized | EP: 3 partitions | 3 TCs shared per auth group | Missing token, expired token, malformed token |
| **403** | Forbidden | EP: 2 partitions | 2 TCs | Wrong role + IDOR (resource owned by other user) |
| **404** | Not Found | EP: 2–3 partitions | 2–3 TCs | Valid ID not in DB + deleted resource + wrong ID type (if typed) |
| **405** | Method Not Allowed | Error Guessing | 1 TC | Wrong HTTP method on endpoint |
| **406** | Not Acceptable | EP | 1 TC | Wrong `Accept` header (pair with 415) |
| **408** | Request Timeout | Error Guessing | 1 TC | Client timeout / upstream slow response |
| **409** | Conflict | State Transition | 1 TC per invalid transition | Concurrent uniqueness violation or invalid state change |
| **410** | Gone | State Transition | 1 TC | Deprecated endpoint or deleted resource (backward-compat context) |
| **413** | Payload Too Large | BVA | 2 TCs (at-limit + over-limit) | File upload or large JSON body size boundary |
| **415** | Unsupported Media Type | EP | 1 TC | Wrong `Content-Type` header |
| **422** | Unprocessable Entity — business rule | Decision Table | 1 per rule violation | Business rule dependency between fields |
| **429** | Too Many Requests | BVA | 2 TCs (at-limit + over-limit) | Rate limit boundary |
| **500** | Internal Server Error | Error Guessing | 1 TC per failure scenario | Minimal set: DB failure, unhandled exception, null/missing external config |
| **502** | Bad Gateway | Error Guessing | 1 TC | Upstream service returns invalid response (API gateway context) |
| **503** | Service Unavailable | Error Guessing | 1 TC | Dependency down / circuit breaker open |
| **504** | Gateway Timeout | Error Guessing | 1 TC | Upstream timeout (API gateway context) |

---

## Auth Error TCs — Shared Pattern

401 TCs are generated ONCE per auth group (all endpoints sharing the same auth scheme) and referenced via traceability — not duplicated per endpoint.

**3 mandatory 401 TCs:**

| TC | Scenario | Request | Expected |
|---|---|---|---|
| 401-MISSING | No Authorization header | `Authorization` header absent | 401 + error body indicating missing credentials |
| 401-EXPIRED | Expired token | Valid format, past `exp` claim | 401 + error body indicating token expired |
| 401-MALFORMED | Malformed token | `Bearer INVALID_TOKEN_FORMAT` | 401 + error body indicating invalid token |

**When to add advanced auth TCs** (only if Feature-Technical explicitly documents the lifecycle):
- Revoked-but-valid token → 401 (token blacklisted)
- Token issued for wrong audience → 403 (valid token, wrong resource)
- Role downgraded mid-session → 403 (session still active, permissions changed)

---

## 403 Forbidden — IDOR Pattern

For any endpoint with path param `{id}` accessing a user-owned resource:

| TC | Scenario | Request | Expected |
|---|---|---|---|
| 403-WRONG-ROLE | User with insufficient role | Valid token, insufficient role | 403 + error body |
| 403-IDOR | User accessing resource owned by another user | Valid token, valid ID owned by user B | 403 + error body (not 404 — do not reveal existence) |

**IDOR privacy note:** 403 (not 404) is the correct response for IDOR — returning 404 reveals that the resource exists, which is an information disclosure.

---

## 404 Handling

| TC | Scenario | Expected |
|---|---|---|
| 404-MISSING | Valid ID format, resource not in DB | 404 + consistent error body |
| 404-DELETED | Resource existed, soft-deleted | 404 (not 200 with deleted flag) |
| 404-WRONG-TYPE | ID in wrong format (e.g. string where UUID expected) | 400 or 404 — document which per spec |

---

## 400 / 422 Field Validation Pattern

**Disambiguation rule:** 400 = input is malformed or structurally invalid. 422 = input is valid syntax but violates a business rule. If the API spec does not distinguish, treat all business-rule violations as 422 scope for TC design.

For each required field or business-rule constraint:
- 1 TC for each missing required field (do NOT generate 1 TC per "missing any field" — each field is separate EP partition)
- 1 TC for each format violation (wrong type, invalid format string)
- 1 TC for each business-rule dependency between fields (Decision Table)

**Cross-field dependency example:**
```
Rule: If `payment_type = CARD` then `card_number` is required
TC-1: payment_type=CARD, card_number=absent → 422
TC-2: payment_type=CASH, card_number=absent → 200 (no card needed)
```

---

## Cross-Cutting Error TCs

Generated once per spec file, shared across relevant endpoints:

### Malformed JSON (POST / PUT / PATCH)
- **TC ID:** `{PROJECT}_F{FID}_ACX_MALFORMED_001_E`
- **Request:** Syntactically invalid JSON body (e.g. `{"name": "test"` — missing closing brace)
- **Expected:** 400 + error body indicating parse failure
- **Applies to:** All POST/PUT/PATCH endpoints — 1 TC, shared

### DB Failure (Endpoints touching DB)
- **TC ID:** `{PROJECT}_F{FID}_ACX_DBFAIL_{TYPE}_E` where TYPE = READ | WRITE | DELETE
- **Precondition:** Simulate DB failure (mock / network partition in test env)
- **Expected:** 500 or 503 + graceful error body (no stack trace exposed)
- **Count:** 1 TC per DB operation type

---

## Error Response Body Contract

All error TCs must assert that the error response body:
1. Contains a machine-readable `code` or `error` field (not just HTTP status)
2. Contains a human-readable `message` field
3. Does NOT expose stack traces, internal file paths, DB query strings, or server version
4. Uses consistent structure across all error codes in the spec

Document the expected error body structure in the API spec; assert it in every error TC.
