defineError
defineError(name, options) declares a typed throwable error with an HTTP status code and an optional Zod payload schema. The HTTP error middleware envelopes thrown instances into structured JSON responses.
Signature
ts
import { defineError } from "@nwire/handler";
function defineError<TSchema extends ZodTypeAny>(
name: string,
options: {
status: number;
schema?: TSchema;
},
): ErrorDefinition<TSchema>;Example
ts
import { defineError } from "@nwire/handler";
import { z } from "zod";
export const UserNotFound = defineError("UserNotFound", {
status: 404,
schema: z.object({ userId: z.string() }),
});
export const EmailAlreadyTaken = defineError("EmailAlreadyTaken", {
status: 409,
schema: z.object({ email: z.string() }),
});Throwing
ts
async ({ input, resolve }) => {
const user = await resolve<UserStore>("users").get(input.id);
if (!user) throw UserNotFound({ userId: input.id });
return user;
}The constructor accepts the payload schema's input shape. The middleware serializes the error as:
json
{
"error": "UserNotFound",
"status": 404,
"details": { "userId": "abc" }
}Built-in errors
@nwire/handler ships the common HTTP errors so you don't have to declare your own for the standard cases:
| Class | Status |
|---|---|
Unauthorized | 401 |
Forbidden | 403 |
NotFound | 404 |
Conflict | 409 |
Gone | 410 |
BadRequest | 400 |
UnprocessableEntity | 422 |
TooManyRequests | 429 |
InternalServerError | 500 |
ts
import { Unauthorized, NotFound, Conflict } from "@nwire/handler";
throw new Unauthorized("missing token");
throw new NotFound("user", input.id);
throw new Conflict("email already taken");OpenAPI integration
Errors a route may throw can be declared in the route's openapi metadata:
ts
.wire(
get("/users/:id", {
params: z.object({ id: z.string() }),
openapi: { throws: [UserNotFound] },
}),
handler,
)The operation declares a 404 response with UserNotFound's shape; clients codegenning against the spec see the typed error.