Skip to content

Packing

Smuggle a full error through transports that only preserve message or cause.

Some layers — certain RPC systems, the boundary into a Cloudflare Durable Object, job queues — only pass along an error’s message (or cause) and throw away every other property. Packing tucks the whole error into one of those fields that do survive, so you can rebuild it on the other side.

import { EErrorPackType } from "@nice-code/error";
// `pack` MUTATES the error in place — it rewrites the chosen field (message/cause) on
// THIS instance and returns the same object (not a clone). The original value is stashed
// internally so `unpack` can restore it.
error.pack(EErrorPackType.msg_pack); // embeds the JSON into error.message
error.pack(EErrorPackType.cause_pack); // embeds the JSON into error.cause

Throw the packed error across the boundary just like any normal Error.

error.unpack(); // restore the original NiceError

In practice you rarely call unpack yourself — castNiceError notices a packed error and unpacks it for you:

import { castNiceError } from "@nice-code/error";
const restored = castNiceError(caught); // unpacks if it was packed
  • A Durable Object only re-throws message when you call into it — pack with msg_pack before throwing inside the DO.
  • A job queue only keeps the error’s message — pack before adding the job, then castNiceError after pulling it off.
  • Any layer where you don’t control how things are serialized and only the standard Error fields make it through.

For boundaries you do control (your own HTTP responses), just use toJsonObject() + castNiceError instead — packing is only for the ones you don’t.