Serialization & Transport
Send typed errors across HTTP and reconstruct them with full types.
A NiceError serializes to plain JSON and reconstructs on the other side — with its ids, context, and HTTP status intact.
Serializing
Section titled “Serializing”const json = error.toJsonObject(); // plain JSON object — safe over HTTPconst str = error.toJsonString(); // JSON stringconst response = error.toHttpResponse(); // a Response with the correct HTTP statusReceiving — castNiceError
Section titled “Receiving — castNiceError”On the receiving side, castNiceError turns any caught value into a NiceError:
import { castNiceError } from "@nice-code/error";
const caught = castNiceError(unknownValue); // always returns a NiceError
if (err_auth.isExact(caught)) { const hydrated = err_auth.hydrate(caught); // deserialize context const { username } = hydrated.getContext("invalid_credentials");}castNiceError handles NiceError instances, serialized JSON objects, native Errors, error-like objects, nullish values, and primitives — it never throws.
One-step — castAndHydrate
Section titled “One-step — castAndHydrate”When you have a specific domain in mind, castAndHydrate casts, checks the domain, and hydrates in a single call:
import { castAndHydrate, matchFirst } from "@nice-code/error";
const error = castAndHydrate(unknownValue, err_auth);// → a hydrated NiceError when it belongs to err_auth, otherwise the raw cast NiceError
if (err_auth.isExact(error)) { const message = matchFirst(error, { invalid_credentials: ({ username }) => `Wrong password for ${username}`, account_locked: () => "Account locked", });}Why hydration matters
Section titled “Why hydration matters”The wire only carries JSON. If an id’s context held a Date, an Error, or anything declared with a custom serialization pair, hydration is what turns the JSON-safe form back into the real typed value. Always hydrate (or castAndHydrate) before reading context that came off a boundary.
A full round trip
Section titled “A full round trip”// Serverreturn error.toHttpResponse();
// Clientconst caught = castNiceError(await res.json());if (err_auth.isExact(caught)) { const hydrated = err_auth.hydrate(caught); // hydrated.getContext(...) is now fully typed and real}Next: Handling errors →