flight_booking_bff
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| flight_booking_bff [2025/12/31 09:18] – pradnya | flight_booking_bff [2026/01/24 05:44] (current) – [Error Handling Strategy] madan | ||
|---|---|---|---|
| Line 15: | Line 15: | ||
| ==== Key Services / Core Components ==== | ==== Key Services / Core Components ==== | ||
| - | ^Service^Responsibility| | + | ^Service^Responsibility^Local Port| |
| - | |**API Gateway / BFF (Node.js)** |Single entry point for UI| | + | |**API Gateway / BFF (Node.js)** |Single entry point for UI|4000| |
| - | |**Auth Service** |Issues & validates tokens| | + | |**Auth Service** |Issues & validates tokens|4001| |
| - | |**Flight Service** |Calls supplier API + Redis cache| | + | |**Flight Service** |Calls supplier API + Redis cache|4002| |
| - | |**Booking Service (MySQL)** |Stores booking data| | + | |**Booking Service (MySQL)** |Stores booking data|4003| |
| - | |**Payment Service** |Payment initiation + webhooks| | + | |**Payment Service** |Payment initiation + webhooks|4004| |
| ==== Observability Stack ==== | ==== Observability Stack ==== | ||
| Line 72: | Line 73: | ||
| ===== Node.js Folder Structure (Clean Architecture) ===== | ===== Node.js Folder Structure (Clean Architecture) ===== | ||
| + | ^Layer^Purpose^Examples^Should define errors?| | ||
| + | |**Domain** |Business rules|Entities, | ||
| + | |**Domain/ | ||
| + | |**Infrastructure** |Technical adapters|DB, | ||
| + | |**Interface/ | ||
| < | < | ||
| + | |||
| src/ | src/ | ||
| ├ api/ | ├ api/ | ||
| | | ||
| | | ||
| - | | + | |
| + | | ||
| ├ domain/ | ├ domain/ | ||
| | | ||
| | | ||
| - | | + | |
| + | | ||
| ├ infrastructure/ | ├ infrastructure/ | ||
| | | ||
| | | ||
| | | ||
| - | | + | |
| + | | ||
| └ tests/ | └ tests/ | ||
| </ | </ | ||
| + | |||
| + | |||
| + | |||
| ===== MySQL — Connection Pool ===== | ===== MySQL — Connection Pool ===== | ||
| Line 491: | Line 504: | ||
| </ | </ | ||
| + | |||
| ====== Error Handling Strategy ====== | ====== Error Handling Strategy ====== | ||
| + | |||
| + | **1. Client Errors (4xx)** | ||
| ^Code^Meaning| | ^Code^Meaning| | ||
| - | |400|validation failure| | + | |400|Bad Request/validation failure| |
| |401|unauthorized| | |401|unauthorized| | ||
| |404|cache expired| | |404|cache expired| | ||
| |409|idempotency conflict| | |409|idempotency conflict| | ||
| |500|internal error| | |500|internal error| | ||
| + | |||
| + | **2. Server Errors (5xx)** | ||
| + | |||
| + | ^Type^Source^Action| | ||
| + | |Dependency Failure|Redis/ | ||
| + | |Timeout|3rd-party API|Fail fast| | ||
| + | |Internal Crash|unexpected bug|Log & alert| | ||
| + | |||
| + | **3. Business Errors** | ||
| + | |||
| + | ^Example^Handling| | ||
| + | |Flight unavailable|409| | ||
| + | |Payment declined|422| | ||
| + | |Invalid state transition|409| | ||
| + | |||
| + | ===== Recommended Placement ===== | ||
| + | |||
| + | **1. ****Business / Domain Errors** | ||
| + | |||
| + | When business rule is violeted - | ||
| + | < | ||
| + | < | ||
| + | |||
| + | < | ||
| + | export class FlightUnavailableError extends Error { | ||
| + | code = ' | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | **2. ****Application Errors** | ||
| + | |||
| + | Use-case level\\ | ||
| + | Validation / workflow / orchestration | ||
| + | |||
| + | / | ||
| + | < | ||
| + | |||
| + | < | ||
| + | export class ValidationError extends Error { | ||
| + | status = 400; | ||
| + | code = ' | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | **3. ****Infrastructure Errors** | ||
| + | |||
| + | ONLY for wrapping technical failures | ||
| + | |||
| + | / | ||
| + | < | ||
| + | |||
| + | < | ||
| + | export class RedisConnectionError extends Error { | ||
| + | code = ' | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | BUT — these should usually be **mapped upward** into application-level errors. | ||
| + | |||
| + | Example mapping: | ||
| + | < | ||
| + | |||
| + | < | ||
| + | try { | ||
| + | await redis.get(key); | ||
| + | } catch(e) { | ||
| + | throw new CacheUnavailableError(); | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | So the **API layer never leaks Redis internals.** | ||
| + | |||
| + | |||
| + | ===== Error Flow (Best Practice) ===== | ||
| + | |||
| + | < | ||
| + | Infrastructure error | ||
| + | ⬇ wrap / map | ||
| + | Application error | ||
| + | ⬇ serialized to client | ||
| + | HTTP response | ||
| + | |||
| + | </ | ||
| + | |||
| + | final structure should look like | ||
| + | |||
| + | < | ||
| + | /src | ||
| + | ┣ /domain | ||
| + | | ||
| + | ┣ / | ||
| + | | ||
| + | ┣ / | ||
| + | | ||
| + | ┗ /api (interfaces) | ||
| + | ┗ error-middleware.ts | ||
| + | |||
| + | </ | ||
| + | |||
| + | **What to AVOID** | ||
| + | |||
| + | Defining all errors in '' | ||
| + | → couples business logic to technology | ||
| + | |||
| + | Throwing raw DB/Redis errors upward\\ | ||
| + | → leaks internal details | ||
| + | |||
| + | Mixed styles (sometimes returning strings, sometimes errors)\\ | ||
| + | → debugging nightmare | ||
flight_booking_bff.1767172737.txt.gz · Last modified: by pradnya
