-module(libero@error). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/libero/error.gleam"). -export_type([never/0, panic_info/0, rpc_error/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Error envelope for Libero RPC responses.\n" "\n" " Every RPC response is shaped as `Result(T, RpcError(E))`, where\n" " `E` is the server function's app-specific error type. The wire\n" " carries this envelope uniformly regardless of whether the server\n" " function itself returns a bare `T` or an explicit `Result(T, E)`.\n" "\n" " ## Three categories of failure\n" "\n" " 1. App errors (`AppError(e)`) are expected, domain-specific\n" " failure modes the server function chose to model, such as\n" " `DuplicateEmail`, `NotFound`, or `ValidationFailed`. Handled\n" " by the app's UI (show a form error, navigate away, and so on).\n" "\n" " 2. Framework errors (`MalformedRequest`, `UnknownFunction`) are\n" " errors in the RPC layer itself. The request was garbage or\n" " named a function that doesn't exist. Usually deployment skew\n" " or a client-side bug.\n" "\n" " 3. Internal errors (`InternalError(trace_id, message)`) are\n" " unexpected runtime panics caught by the dispatch layer. The\n" " `trace_id` is opaque to the client; the full panic details\n" " are logged server-side under that id. The `message` field\n" " contains a client-safe string suitable for display to end\n" " users without exposing internal details.\n" "\n" " ## Bare-T server functions\n" "\n" " Server functions that return a bare type (`List(Record)`, `Int`,\n" " `Option(Note)`, and so on) are exposed to clients as\n" " `Result(T, RpcError(Never))`, where `Never` is an uninhabited\n" " type. Gleam's exhaustiveness checker understands that `Never`\n" " can't be constructed, so the `AppError(_)` match arm is\n" " statically unreachable and users don't need to write it.\n" ). -type never() :: any(). -type panic_info() :: {panic_info, binary(), binary(), binary()}. -type rpc_error(WXV) :: {app_error, WXV} | malformed_request | {unknown_function, binary()} | {internal_error, binary(), binary()}.