--- title: "App Error" slug: "app-error" updated: 2026-08-26T07:29:40Z published: 2026-08-26T07:29:40Z canonical: "docs.viewlift.com/app-error" --- > ## 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. # App Error ## AppError `AppError` is the canonical error type used throughout ONECMS. It represents a normalized, externally safe error contract that is independent of framework, transport, or UI concerns. ## Purpose `AppError` exists to enforce one invariant: > All errors crossing architectural boundaries must have a stable code, safe message, and clear transport semantics. It provides a single, predictable shape for errors across: - services - domain logic - transports - UI boundaries ## What AppError Is - A domain-level error primitive - Stable and serializable - Explicitly coded (via `ErrorCode`) - Safe to expose externally ## What AppError Is Not `AppError` is not: - an exception hierarchy - a business-rule engine - a logging mechanism - a retry signal - a framework-specific error type It does not contain logic beyond normalization and representation. ## Structure An `AppError` instance always contains: - `code` — stable error identifier - `status` — HTTP / transport semantics - `message` — externally safe, human-readable message - `meta` (optional) — structured diagnostic context - `cause` (optional) — original error (never exposed externally) ## Creation Rules ### `AppError.create` ``` AppError.create(code: ErrorCode, options?: AppErrorOptions): AppError ``` - Creates a new `AppError` from a known error code - Resolves: - HTTP status - default message - Allows optional overrides: - `message` - `meta` - `cause` Use this when: - you are intentionally raising a known failure - the error condition is understood and explicit ### `AppError.from` ``` AppError.from(err: unknown, fallbackCode?: ErrorCode): AppError ``` This is the only allowed place where `unknown` is handled. Behavior: - If `err` is already an `AppError`, it is returned as-is - If `err` is an `Error`, it is wrapped using the fallback code - If `err` is anything else, it is normalized into an `AppError` This guarantees: - no `unknown` escapes - error shape is always deterministic ## Serialization ### `toJSON()` ``` { code: string; message: string; status: number; meta?: Record; } ``` - This is the only safe external representation - `cause` is never exposed - Transport adapters must rely on this shape ## ErrorMap `ErrorMap` defines the authoritative registry of error codes and their semantics. It is policy, not logic. ### ErrorMap Invariants The following rules are strict and non-negotiable: - Error codes are stable and never reused - Messages are safe to expose externally - `status` represents transport semantics only - No business logic is allowed - No helpers, factories, or functions are allowed `ErrorMap` must remain a plain, declarative object. ### Error Codes Each entry in `ErrorMap` defines: ``` { status: number; message: string; } ``` Categories are namespaced for clarity, e.g.: - `system.*` - `validation.*` - `auth.*` - `resource.*` - `domain.*` - `db.*` - `external.*` - `config.*` Namespaces are organizational only; semantics come from the code itself. ## Relationship to Other Layers **AsyncHandler** - `AsyncHandler` guarantees that only `AppError` escapes execution boundaries - `AppError` defines the normalized shape used downstream **Transport Error Adapters** - Transports map `AppError.status` → protocol status - `toJSON()` is used as the response body - No transport-specific logic belongs inside `AppError` **UI Error Boundaries** - UI receives a sanitized error - UI must not branch on internal error codes by default - Recovery and presentation are UI concerns, not error concerns ## Design Principles ### Stability Over Convenience Error codes are contracts. Changing or reusing codes breaks consumers. ### Explicitness Over Inference If an error matters, it must have: - a code - a place in `ErrorMap` No implicit or ad-hoc errors. ### Separation of Concerns - AppError → shape and normalization - ErrorMap → policy and semantics - Transports → protocol adaptation - UI → presentation and recovery Each layer stays boring and focused. ## Summary `AppError` and `ErrorMap` together form the spine of error handling in ONECMS. They ensure that: - errors are predictable - boundaries are respected - failures are safe to expose - systems fail loudly and consistently If an error bypasses `AppError`, the system is broken.