Handling Errors
Route errors with composable handlers or a reusable handler class.
nice-code offers two handling styles: a composable functional API, and a reusable class.
Functional style
Section titled “Functional style”Build a list of cases with forId, forIds, and forDomain. handleWithSync runs the first matching case and returns whether anything handled it.
import { forDomain, forId, forIds } from "@nice-code/error";
const handled = error.handleWithSync([ forId(err_auth, "invalid_credentials", (h) => { const { username } = h.getContext("invalid_credentials"); return res.status(401).json({ error: `Bad credentials for ${username}` }); }), forIds(err_auth, ["account_locked", "rate_limited"], (h) => { return res.status(h.httpStatusCode).json({ error: h.message }); }), forDomain(err_payment, (h) => { return res.status(500).json({ error: "Payment failed" }); }),]);The handler argument (h) is narrowed to the matched id(s), so getContext is typed inside each case.
Async handlers
Section titled “Async handlers”await error.handleWithAsync([ forDomain(err_payment, async (h) => { await db.logFailure(h.message); await notify(h.toJsonObject()); }),]);Class-based style
Section titled “Class-based style”NiceErrorHandler is a reusable handler you configure once and apply to many errors — ideal for a central error boundary.
import { NiceErrorHandler } from "@nice-code/error";
const handler = new NiceErrorHandler() .forId(err_auth, "invalid_credentials", (h) => "unauthorized") .forDomain(err_payment, (h) => "payment_error") .setDefaultHandler((e) => "unknown_error");
handler.handleErrorWithPromiseInspection(error);Choosing a style
Section titled “Choosing a style”- Functional — local, one-off routing inside a single catch block.
- Class-based — a shared, reusable policy you register once (server middleware, a global boundary).