--- title: "Overview" slug: "overview-1" updated: 2026-08-26T07:41:45Z published: 2026-08-26T07:41:45Z canonical: "docs.viewlift.com/overview-1" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.viewlift.com/llms.txt > Use this file to discover all available pages before exploring further. # Overview ## Overview This document describes the error handling architecture used across ONECMS. Error handling is intentionally layered, explicit, and boring. Each layer has a single responsibility and a clear boundary. ## Design Goal The error system exists to enforce one invariant: > Errors must be predictable, normalized, safe to expose, and handled at the correct layer. No layer attempts to do more than its job. ## The Error Flow (High Level) ![Image](https://cdn.document360.io/15e0c142-c823-4c77-a8e8-9d32ca937982/Images/Documentation/Screenshot%202026-08-26%20at%201.11.12%E2%80%AFPM.png) Each step exists for a reason. Skipping or collapsing layers leads to leakage and ambiguity. ## Layer Responsibilities ### 1. Execution Boundaries — AsyncHandler **Responsibility:** Normalize anything throwable into a deterministic error shape. - Explicitly wraps execution - Converts `unknown` → `AppError` - Preserves existing `AppError` instances - Framework-agnostic `AsyncHandler` is: - opt-in - not middleware - not global It establishes a failure boundary, nothing more. ### 2. UI Async Boundaries — GenericTryCatch **Responsibility:** Provide structured try/catch/finally for UI-initiated async operations. - Wraps a `run` function with `setLoading`, `onError`, and `onFinally` hooks - Returns a fallback value on error when provided - Re-throws normalized errors when no fallback is given - Complements `AsyncHandler` — used at the UI layer rather than service boundaries `GenericTryCatch` is: - opt-in - stateless (single static method) - independent of `AppError` (normalizes `unknown` → `Error`) ### 3. Error Primitive — AppError **Responsibility:** Represent errors in a stable, externally safe form. An `AppError` always contains: - a stable error code - a safe message - transport semantics (status) - optional structured metadata - an internal cause (never exposed) `AppError` is: - portable - serializable - framework-independent ### 4. Error Policy — ErrorMap **Responsibility:** Define the authoritative registry of error semantics. `ErrorMap`: - maps error codes → status + message - contains no logic - contains no helpers - defines policy, not behavior Error codes are contracts. They are stable and never reused. ### 5. Transport Error Adapters **Responsibility:** Adapt `AppError` to protocol-specific responses. Examples: - HTTP API error responses - GraphQL error mapping - background job failure reporting Transport adapters: - read `AppError.status` - serialize via `toJSON()` - must not infer or mutate error meaning This is the only place where transport semantics apply. ### 6. UI Error Boundary **Responsibility:** Contain unhandled failures and protect the user experience. The UI Error Boundary: - runs only in the client - presents a safe fallback UI - offers recovery actions - avoids branching on internal error codes It does not: - fix errors - retry logic - perform domain decisions It contains failure — nothing else. ## What Error Handling Is Not Error handling in ONECMS does not: - rely on global interception - mix business logic with presentation - allow `unknown` to leak - branch UI on internal codes by default - embed retry or orchestration logic in errors If you see any of the above, the boundary is wrong. ## Common Anti-Patterns to Avoid - ❌ Throwing raw `Error` across layers - ❌ Handling `unknown` outside `AppError.from` - ❌ Using UI error boundaries for control flow - ❌ Encoding business rules in `ErrorMap` - ❌ Treating `AsyncHandler` as middleware Each of these breaks a layer contract. ## Why This Architecture Works Because it enforces: **Explicit boundaries** No hidden interception or magic. **Deterministic behavior** Same error → same shape → same handling. **Safe exposure** Internal causes never leak. **Composable layers** Execution, transport, and UI remain independent. Most importantly: > Failures become boring. ## Mental Model Summary | Layer | Responsibility | | --- | --- | | AsyncHandler | Normalize execution failures | | GenericTryCatch | Structured UI async boundaries | | AppError | Define error shape | | ErrorMap | Define error semantics | | Transport Adapters | Protocol mapping | | UI Error Boundary | User-facing containment | If each layer stays in its lane, error handling stays predictable. ## Final Note Error handling is not about preventing failure. It is about containing failure correctly. When errors feel boring, understandable, and consistent — the system is working as designed.