Files
Krow-workspace/docs/ERROR_HANDLING_ARCHITECTURE.md

132 lines
6.2 KiB
Markdown

# Centralized Error Handling Architecture
**Project:** KROW Workforce Mobile App
## 1. Executive Summary
We have implemented a **Centralized Error Handling System** that ensures the entire application (Staff & Client) handles errors consistently, reliably, and with full localization support.
Instead of writing error handling code in every single feature (which leads to bugs and inconsistent messages), we rely on a global safety net that catches **Network Failures**, **Server Errors (500)**, **Not Found Errors (404)**, and **Business Logic Violations** automatically.
### Key Benefits
* **Safety:** The app never crashes due to unhandled API errors.
* **Consistency:** A network error looks the same in "Shifts" as it does in "billing".
* **Localization:** All error messages are automatically translated (English/Spanish).
* **Speed:** Developers can build features faster without worrying about `try/catch` blocks.
### Technical Excellence (Status Code Handling)
We don't just catch "errors"; we understand them. The system automatically categorizes and handles:
* **500 (Server Error):** "Our servers are having a moment. Please try again."
* **404 (Not Found):** "The resource you're looking for (Shift/Profile) is missing."
* **401 (Unauthorized):** "Your session expired. Please log in again." (Auto-redirect)
* **403 (Forbidden):** "You don't have permission to access this area."
* **503 (Unavailable):** "Maintenance mode or overloaded. Back in a bit!"
---
## 2. Architecture Overview
The error handling flows through three distinct layers, ensuring separation of concerns:
```mermaid
graph TD
A[Data Layer / Repository] -->|Throws AppException| B[BLoC Layer / State Management]
B -->|Emits Error Key| C[UI Layer / Presentation]
subgraph "1. Data Layer (The Guard)"
A -- Captures Exceptions --> D[DataErrorHandler Mixin]
D -- Maps to --> E[NetworkException, ServerException, etc.]
end
subgraph "2. BLoC Layer (The Translator)"
B -- Uses --> F[BlocErrorHandler Mixin]
F -- Catches AppException --> G[converts to 'errors.category.type']
end
subgraph "3. UI Layer (The Messenger)"
C -- Calls --> H["translateErrorKey()"]
H -- Returns --> I["Localized String (e.g. 'Sin conexión')"]
end
```
### 1. The Data Layer (The Guard)
* **Role:** Wraps all API calls.
* **Mechanism:** Catches raw errors (SocketException, FirebaseException) and converts them into domain-specific `AppExceptions` (e.g., `NetworkException`).
* **Location:** `packages/data_connect/lib/src/mixins/data_error_handler.dart`
### 2. The BLoC Layer (The Logic)
* **Role:** Manages state.
* **Mechanism:** Uses `handleError` helper to execute logic. If an `AppException` bubbles up, it automatically emits a failure state with a **Message Key** (e.g., `errors.auth.session_expired`).
* **Location:** `packages/core/lib/src/presentation/mixins/bloc_error_handler.dart`
### 3. The UI Layer (The Presenter)
* **Role:** Shows the message.
* **Mechanism:** Observes the state. When an error occurs, it passes the key to `translateErrorKey(key)` which returns the user-friendly text from the active language file (e.g., `es.i18n.json`).
* **Location:** `packages/core_localization/lib/src/utils/error_translator.dart`
---
## 3. Verified Features
The following features have been audited and are confirmed to use the Centralized Error Handler:
### **✅ Core Infrastructure**
* Authentication (Login/Signup)
* Firebase Data Connect Integration
* Localization Engine
### **✅ Staff App Features**
| Feature | Status | Notes |
| :--- | :---: | :--- |
| **Shifts** | ✅ | Handles availability, accept, history errors |
| **Profile** | ✅ | Personal info, experience, attire updates |
| **Onboarding** | ✅ | Tax forms (W4/I9), emergency contacts |
| **Compliance** | ✅ | Document uploads, certificate management |
| **Financials** | ✅ | Bank accounts, time cards, payments |
| **Availability** | ✅ | Weekly schedule blocking |
| **Clock In** | ✅ | Location/Time validation errors |
### **✅ Client App Features**
| Feature | Status | Notes |
| :--- | :---: | :--- |
| **Auth** | ✅ | Login, Signup failures |
| **Create Order** | ✅ | Type selection, validation |
| **View Orders** | ✅ | Loading lists, filtering |
| **Hubs** | ✅ | NFC assignment errors |
| **Billing** | ✅ | Payment methods, invoicing |
| **Coverage** | ✅ | Dashboard metric loading |
---
## 4. How to Verify (Demo Script)
### Test A: The "Tunnel" Test (Network)
1. Open the app to the **Shifts** page.
2. Toggle **Airplane Mode ON**.
3. Pull to refresh the list.
4. **Result:** App shows a gentle `snackbar` error: *"No internet connection"* (or Spanish equivalent). **No Crash.**
### Test B: The "Duplicate Data" Test (Smart Validation)
1. Log in on two devices with the same account (if possible) or simply use a known registered email.
2. Go to the **Sign Up** page.
3. Try to register a new account using that *existing* email.
4. **Result:** App instantly displays specific, helpful feedback: *"An account with this email already exists."* instead of a generic failure.
5. **Why it matters:** Proves the backend and frontend are synced to guide the user, not just block them.
### Test C: The "Crash Proof" Test (The Safety Net)
1. **Scenario:** Even if a developer introduces a bug (like a random exception) or the server returns a 500 status.
2. **Result:** The app catches the unknown error, logs it internally, and shows a safe default message: *"Something went wrong. Please try again."*
3. **Why it matters:** The app never crashes or closes unexpectedly, preserving user trust.
### Test D: The "Language" Test (Localization)
1. Trigger an error (like wrong password).
2. Change phone language to **Spanish**.
3. Trigger the same error.
4. **Result:** Message automatically translates: *"Correo electrónico o contraseña inválidos."*
---
## 5. Code Locations (Reference)
* **Exceptions:** `packages/domain/lib/src/exceptions/app_exception.dart`
* **Data Mixin:** `packages/data_connect/lib/src/mixins/data_error_handler.dart`
* **Bloc Mixin:** `packages/core/lib/src/presentation/mixins/bloc_error_handler.dart`
* **Translator:** `packages/core_localization/lib/src/utils/error_translator.dart`
* **Strings:** `packages/core_localization/lib/src/l10n/*.i18n.json`