Skip to content

HttpError

HttpError is an Error subclass you throw from an authorize function or a route handler to control the HTTP status and payload of the error response. It is re-exported from @toapi/server (defined in @toapi/common). When the request handler catches an HttpError, it responds with the given status, a JSON body of { message, data }, and Content-Type: application/json+httperror — a shape the client understands and rethrows.

class HttpError<Data = any> extends Error {
status: number;
data?: Data;
constructor(status: number, message: string, data?: Data);
}
Argument Type Description
status number The HTTP status code to send (e.g. 401, 404, 422).
message string A human-readable error message, sent as message in the JSON body.
data Data (optional) Arbitrary extra payload, sent as data in the JSON body — for example field-level validation details.
import { defineHandler, HttpError, TResponse } from "@toapi/server";
export const GET = defineHandler(
{
authorize: (req) => {
const token = req.headers.get("Authorization");
if (!token) throw new HttpError(401, "Unauthorized");
return verify(token);
},
},
async () => TResponse.json({ ok: true }),
);

Signal a not-found or validation error in a handler

Section titled “Signal a not-found or validation error in a handler”
export const GET = defineHandler(
{ authorize: () => true, params: { id: z.string() } },
async (req) => {
const book = await db.books.find(req.params().id);
if (!book) throw new HttpError(404, "Book not found");
return TResponse.json(book);
},
);
throw new HttpError(422, "Validation failed", {
fields: { email: "already in use" },
});

The client receives the status, message, and data, letting you branch on typed error details.