# error-envelope ## Purpose Defines Zod schemas for the standard error response envelope used across all Suaveplan API endpoints. By sharing these schemas between server route handlers, React error-boundary hooks, and OpenAPI generators, every layer of the stack interprets error responses identically — no per-client parsing logic, no mismatched field names, and consistent TypeScript types end-to-end. ## Features - `ErrorEnvelope` schema — `{code, message, details?}` base shape: stable machine-readable code, human-readable message, and an open-typed optional details field - `FieldError` schema — per-field validation error descriptor with dot-notation field path, message, and optional code; suitable for populating `details` on 422 responses - `ValidationErrorEnvelope` schema — extends `ErrorEnvelope` with `details: FieldError[]` for typed 422 Unprocessable Entity responses - Stable `code` strings enable programmatic error handling without string matching on `message` - `details` typed as `z.unknown()` in the base `ErrorEnvelope` to remain flexible; `ValidationErrorEnvelope` provides the typed narrowing for validation failures - Full TypeScript inference via `z.infer<>` — no manual interface duplication - Zod v4 compatible ## Usage: Basic Example ```ts import { ErrorEnvelope } from "@suaveplan/api-schemas/common"; // Parse an error response body from a failed API call const error = ErrorEnvelope.parse({ code: "AUTH_TOKEN_EXPIRED", message: "The access token has expired.", }); // → { code: "AUTH_TOKEN_EXPIRED", message: "The access token has expired." } ``` ## Usage: Advanced Example ```ts import { ValidationErrorEnvelope } from "@suaveplan/api-schemas/common"; // Parse a 422 response body with per-field errors const validationError = ValidationErrorEnvelope.parse({ code: "VALIDATION_FAILED", message: "Request body failed validation.", details: [ { field: "email", message: "Must be a valid email address.", code: "INVALID_EMAIL" }, { field: "password", message: "Must be at least 8 characters.", code: "TOO_SHORT" }, ], }); // Display field errors in a React form for (const fieldErr of validationError.details) { console.log(`${fieldErr.field}: ${fieldErr.message}`); } ``` ## API Reference ### `ErrorEnvelope` Zod object schema — base error shape for all API error responses. | Field | Type | Description | |-----------|--------------------|--------------------------------------------------------| | `code` | `string` (min 1) | Stable machine-readable error code | | `message` | `string` (min 1) | Human-readable error description | | `details` | `unknown` | Optional structured context (field errors, sub-errors)| **Type export:** `type ErrorEnvelope = z.infer` ### `FieldError` Zod object schema — per-field validation failure descriptor. | Field | Type | Description | |-----------|-------------------|--------------------------------------------------| | `field` | `string` (min 1) | Dot-notation path to the offending field | | `message` | `string` (min 1) | Human-readable validation failure description | | `code` | `string` | Optional machine-readable field-error code | **Type export:** `type FieldError = z.infer` ### `ValidationErrorEnvelope` Extends `ErrorEnvelope` — typed 422 response envelope. | Field | Type | Description | |-----------|-----------------|------------------------------------------| | `code` | `string` | Inherited from `ErrorEnvelope` | | `message` | `string` | Inherited from `ErrorEnvelope` | | `details` | `FieldError[]` | Array of per-field validation errors | **Type export:** `type ValidationErrorEnvelope = z.infer` ## Implementation Notes The base `ErrorEnvelope.details` field is typed as `z.unknown()` to support the full range of structured error payloads that Suaveplan endpoints may return — not just field validation errors but also rate-limit metadata, conflict information, or retry-after hints. Callers that know they are dealing with a validation error should narrow to `ValidationErrorEnvelope` rather than relying on `details` being `unknown`.