Replace all ~1,086 occurrences of Wizamart/wizamart/WIZAMART/WizaMart with Orion/orion/ORION across 184 files. This includes database identifiers, email addresses, domain references, R2 bucket names, DNS prefixes, encryption salt, Celery app name, config defaults, Docker configs, CI configs, documentation, seed data, and templates. Renames homepage-wizamart.html template to homepage-orion.html. Fixes duplicate file_pattern key in api.yaml architecture rule. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
18 KiB
18 KiB
Error Handling System - Flow Diagram
Request Processing Flow
┌─────────────────────────────────────────────────────────────────┐
│ Incoming HTTP Request │
└─────────────────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Store Context Middleware (FIRST) │
│ - Detects store from domain/subdomain/path │
│ - Sets request.state.store │
│ - Sets request.state.store_context │
└─────────────────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Context Detection Middleware (NEW) │
│ - Detects request context type │
│ - Sets request.state.context_type │
│ • API, ADMIN, STORE_DASHBOARD, SHOP, FALLBACK │
└─────────────────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Route Handler Execution │
│ - Process business logic │
│ - May throw exceptions │
└─────────────────────────────────┬───────────────────────────────┘
│
┌─────────────┴─────────────┐
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Success │ │ Exception │
│ Response │ │ Raised │
└──────────────┘ └──────┬───────┘
│
▼
┌────────────────────────────────────────────────────────┐
│ Exception Handler │
│ - OrionException │
│ - HTTPException │
│ - RequestValidationError │
│ - Generic Exception │
│ - 404 Not Found │
└────────────────────┬───────────────────────────────────┘
│
┌─────────────┴────────────┐
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Special Case: │ │ General Error │
│ 401 on HTML │ │ Handling │
│ → Redirect to │ │ │
│ Login │ │ │
└──────────────────┘ └─────────┬────────┘
│
┌─────────────┴─────────────┐
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ API Request? │ │ HTML Request? │
│ /api/* path │ │ GET + text/html │
└────────┬─────────┘ └─────────┬────────┘
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────────────┐
│ Return JSON │ │ Error Page Renderer │
│ Response │ │ │
│ { │ │ - Detect context type │
│ error_code, │ │ - Select template │
│ message, │ │ - Prepare data │
│ status_code │ │ - Render HTML │
│ } │ └──────────┬───────────────┘
└──────────────────┘ │
▼
┌──────────────────────────────┐
│ Template Selection │
│ │
│ Priority: │
│ 1. {context}/errors/{code} │
│ 2. {context}/errors/generic│
│ 3. shared/{code}-fallback │
│ 4. shared/generic-fallback │
└──────────┬───────────────────┘
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Admin │ │ Store │ │ Shop │
│ Error │ │ Error │ │ Error │
│ Page │ │ Page │ │ Page │
│ │ │ │ │ (Themed) │
└─────────────┘ └─────────────┘ └─────────────┘
Context Detection Logic
┌──────────────────────────────────────────────────────────────────┐
│ Request Arrives │
│ (host + path) │
└────────────────────────────┬─────────────────────────────────────┘
│
▼
┌──────────────────┐
│ Path starts │───YES───→ API Context
│ with /api/ ? │ (Always JSON)
└────────┬─────────┘
│ NO
▼
┌──────────────────┐
│ Host starts │───YES───→ ADMIN Context
│ with admin. │ (Admin Portal)
│ OR path starts │
│ with /admin ? │
└────────┬─────────┘
│ NO
▼
┌──────────────────┐
│ Path starts │───YES───→ STORE_DASHBOARD Context
│ with /store/ ? │ (Store Management)
└────────┬─────────┘
│ NO
▼
┌──────────────────┐
│ Store object │───YES───→ SHOP Context
│ in request │ (Customer Storefront)
│ state? │
└────────┬─────────┘
│ NO
▼
┌──────────────────┐
│ FALLBACK │
│ Context │
│ (Unknown) │
└──────────────────┘
Template Selection Example
For a 404 error in ADMIN context:
1. Check: app/templates/admin/errors/404.html ✓ EXISTS → USE THIS
2. Check: app/templates/admin/errors/generic.html (skipped)
3. Check: app/templates/shared/404-fallback.html (skipped)
4. Check: app/templates/shared/generic-fallback.html (skipped)
For a 429 error in SHOP context (not created yet):
1. Check: app/templates/shop/errors/429.html ✗ Missing
2. Check: app/templates/shop/errors/generic.html ✗ Missing
3. Check: app/templates/shared/429-fallback.html ✗ Missing
4. Check: app/templates/shared/generic-fallback.html ✓ EXISTS → USE THIS
Error Response Types
┌──────────────────────────────────────────────────────────────────┐
│ Request Type │
└───────────┬─────────────┬───────────────────┬─────────────────────┘
│ │ │
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌──────────────┐
│ API │ │ HTML Page │ │ 401 on HTML │
│ Request │ │ Request │ │ Page │
└──────┬─────┘ └──────┬─────┘ └──────┬───────┘
│ │ │
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌──────────────┐
│ JSON │ │ Rendered │ │ Redirect │
│ Response │ │ HTML │ │ to Login │
│ │ │ Error │ │ │
│ { │ │ Page │ │ 302 Found │
│ error_code│ │ │ │ Location: │
│ message │ │ Context- │ │ /admin/login│
│ status │ │ aware │ │ /store/login│
│ details │ │ template │ │ /shop/login │
│ } │ │ │ │ │
└────────────┘ └────────────┘ └──────────────┘
Example Scenarios
Scenario 1: API 404 Error
Request: GET /api/v1/admin/stores/999
Context: API
Result: JSON { "error_code": "STORE_NOT_FOUND", ... }
Scenario 2: Admin Page 404 Error
Request: GET /admin/nonexistent
Accept: text/html
Context: ADMIN
Result: HTML admin/errors/404.html
Scenario 3: Shop Page 500 Error
Request: GET /products/123 (on store1.platform.com)
Accept: text/html
Context: SHOP (store detected)
Result: HTML shop/errors/500.html (with store theme)
Scenario 4: Unauthorized Access to Admin
Request: GET /admin/settings
Accept: text/html
No valid session
Context: ADMIN
Result: 302 Redirect to /admin/login
Debug Information Display
┌──────────────────────────────────────────────────────────────┐
│ Error Page Display │
└──────────────────────┬───────────────────────────────────────┘
│
┌───────────┴───────────┐
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Admin User │ │ Other Users │
│ (Context: │ │ (Store, │
│ ADMIN) │ │ Shop) │
└──────┬───────┘ └──────┬───────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Debug Info │ │ No Debug │
│ SHOWN: │ │ Info: │
│ • Path │ │ │
│ • Error code │ │ Only user- │
│ • Details │ │ friendly │
│ • Stack │ │ message │
└──────────────┘ └──────────────┘
File Organization
app/
├── exceptions/
│ ├── handler.py # Exception handlers (refactored)
│ ├── error_renderer.py # NEW: Renders error pages
│ └── base.py # Base exceptions
│
├── templates/
│ ├── admin/
│ │ └── errors/ # NEW: Admin error pages
│ │ ├── base.html # Base template
│ │ ├── 404.html # Specific errors
│ │ └── generic.html # Catch-all
│ │
│ ├── store/
│ │ └── errors/ # TODO: Store error pages
│ │
│ ├── shop/
│ │ └── errors/ # TODO: Shop error pages (themed)
│ │
│ └── shared/
│ └── *-fallback.html # Shared fallback error pages
middleware/
├── store_context.py # Store detection (existing)
├── context_middleware.py # NEW: Context detection
└── theme_context.py # Theme loading (existing)
Benefits Summary
✅ Separation of Concerns: HTML templates separate from handler logic ✅ Context-Aware: Different error pages for different areas ✅ Maintainable: Easy to update individual error pages ✅ Scalable: Easy to add new contexts or error types ✅ Professional: Polished error pages matching area design ✅ Flexible: Fallback mechanism ensures errors always render ✅ Secure: Debug info only shown to admins ✅ Themed: Shop errors can use store branding (Phase 3)
This flow ensures that:
- API calls ALWAYS get JSON responses
- HTML page requests get appropriate error pages
- Each context (admin/store/shop) has its own error design
- Fallback mechanism prevents broken error pages
- 401 errors redirect to appropriate login pages