132 lines
6.2 KiB
Markdown
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`
|