Overview
Step 7: systematically handle edge cases. Interviewers probe boundaries and failures: empty and full states, invalid input, duplicate requests, concurrency races, timeouts, partial failures in multi-step flows, and time-related issues. A structured checklist lets you cover them quickly and shows production maturity.
Useful categories: input validation (nulls, negatives, unknown IDs), state rules (illegal transitions), capacity (full, empty, limits), concurrency (two users, same resource), external failures (payment down, timeout), idempotency (retries, double clicks), and time (expiry, time zones, daylight saving). Each should map to a check, a domain exception, or a compensation.
Pilots do not rely on memory for failure scenarios; they run through a list: engine failure, low fuel, bad weather. A checklist ensures nothing obvious is missed under pressure.
When to use it
- After the main flow works.
- When the interviewer asks 'what could go wrong?'.
- Before finalizing any design.
Where it shows up in interviews
Recognize it when: 'what if two users...', 'what if payment fails...'
- Design a movie ticket system
- Design an ATM
- Design a parking lot
Where it is used in real software
Teams inject failures to verify handling of timeouts and outages.
Stripe and payment APIs require idempotency to handle retries safely.
QA practice of testing at and around limits (0, 1, max, max+1).
Key terms
- Boundary value
- Values at the edge of valid ranges.
- Race condition
- Timing-dependent incorrect behavior.
- Partial failure
- Some steps succeeded, others failed.
- Idempotency
- Repeating a request has no extra effect.
- Compensation
- Undoing earlier steps after failure.
How it works, step by step
- 1Inputs
Null, empty, negative, unknown IDs, too many items.
- 2States
Actions in the wrong state (confirm an expired hold).
- 3Capacity
Full, empty, exactly at limit.
- 4Concurrency
Two actors, same resource at the same time.
- 5Failures and retries
External errors, timeouts, duplicate requests, time boundaries.
Edge cases for the movie ticket system
Checklist results
| Category | Edge case | Handling |
|---|---|---|
| Input | Seat ID not in screen | IllegalArgument / 400 |
| State | Confirm after hold expired | HoldExpired; auto-refund if charged |
| Capacity | Request 11 seats, limit 10 | Reject with clear message |
| Concurrency | Two users hold the same seat | Atomic all-or-nothing hold |
| External | Payment timeout (unknown result) | Query payment status; idempotency key |
| Idempotency | User double-clicks Pay | Same key returns same booking |
| Time | Show already started | Reject new holds |
NOWCategory: Input | Edge case: Seat ID not in screen | Handling: IllegalArgument / 400
Seven categories cover what interviewers typically ask, each with a concrete answer.
Implementation
class BookingService { private processedKeys = new Map<string, Booking>(); constructor(private shows: ShowRepository, private payments: PaymentGateway, private now = () => Date.now()) {} async confirm(holdId: string, idempotencyKey: string): Promise<Booking> { const existing = this.processedKeys.get(idempotencyKey); if (existing) return existing; // double click / retry const hold = this.shows.findHold(holdId); if (!hold) throw new NotFound("Unknown hold"); // input const show = this.shows.get(hold.showId); if (show.startsAt <= this.now()) throw new Conflict("Show already started"); // time if (hold.expiresAt <= this.now()) { show.release(hold); throw new Gone("Hold expired"); } // state let paid: boolean; try { paid = await this.payments.charge(hold.userId, hold.totalCents, { idempotencyKey }); } catch (e) { paid = await this.payments.wasCharged(idempotencyKey); // timeout: unknown outcome if (!paid) { show.release(hold); throw e; } } if (!paid) { show.release(hold); throw new PaymentDeclined(); } // external failure const booking = show.confirm(hold); this.processedKeys.set(idempotencyKey, booking); return booking; }}Complexity and performance
Input, state, capacity, concurrency, external, idempotency, time.
Discuss, then code the important ones.
Trade-offs
Mention all categories briefly; implement the most critical (concurrency, payment failure).
Strict validation prevents bugs but may frustrate users; give clear messages.
Variants and related techniques
Generate random inputs to find edge cases automatically.
Document each failure, detection, and response.
Common mistakes
- Only the happy path.
Fix: Run the checklist before saying 'done'.
- Treating timeouts as failures.
Fix: A timeout means unknown outcome; check status before retrying.
- Silently ignoring invalid input.
Fix: Reject with specific domain errors.
Interview questions
What happens if the payment call times out?
The outcome is unknown, so do not assume failure. Query the payment status using the idempotency key; if charged, confirm the booking; if not, release the hold. Retries use the same key so the customer is never charged twice.
How do you systematically find edge cases?
Use a checklist: invalid inputs, illegal state transitions, capacity boundaries, concurrent access, external failures and timeouts, duplicate requests, and time-related issues like expiry and time zones.
Practice problems
| Problem | Difficulty | What it trains |
|---|---|---|
| List edge cases for a parking lot | Easy | Checklist. |
| Handle payment timeouts in a booking flow | Hard | Unknown outcomes. |