Beta
The fixed set of per-status HttpError subclasses your generated TypeScript client throws, and how handleHttpError picks one.
This page covers the hosted CodeForge engine only. It documents what your generated TypeScript client throws for a non-OK response — not the OSS The Codegen Project CLI, which has its own docs.
Nothing to configure. Any document that generates an http_client protocol gets the fixed set
of error classes below, whether or not your OpenAPI document declares any of these statuses.
The class names stay stable across spec changes, since they never depend on what your document
declares.
| Class | Status |
|---|---|
BadRequestError | 400 |
AuthenticationError | 401 |
PermissionDeniedError | 403 |
NotFoundError | 404 |
ConflictError | 409 |
UnprocessableEntityError | 422 |
RateLimitError | 429 |
InternalServerError | any status >= 500 |
Every class extends the same HttpError your client already throws, carrying status,
statusText, and the parsed response body (typed unknown on every class — the generator does
not attempt to type an error body per operation). Each exact-status class narrows status to its
literal (readonly status: 404 on NotFoundError); InternalServerError keeps status: number,
since the class covers a whole range rather than one code — check status to tell a 500 from a
503.
A status outside this fixed set — 402, 410, or any other 4xx the set does not name — still throws
plain HttpError.
handleHttpError picks the class from the live response status, independent of which statuses
your OpenAPI document declares:
>= 500 becomes InternalServerError.HttpError.A server returning a status your document never declared — a 429 on an operation with no
documented rate limit — still gets RateLimitError. Only the error message varies by
declaration: a status your document documents gets the documented reason phrase; an undeclared
one gets a generic HTTP Error: <status> <statusText> message. The class thrown never depends on
that distinction.
Every subclass is also an instanceof HttpError, so an existing catch-all keeps working
unchanged. Both HttpError and every subclass import directly from your generated package's
root, alongside the client class — no subpath needed. Narrow first when you need to handle one
status differently:
import { HttpError, NotFoundError } from 'your-sdk'
try {
await client.getPet({ parameters: { petId: '1' } })
} catch (error) {
if (error instanceof NotFoundError) {
// error.status is narrowed to 404
} else if (error instanceof HttpError) {
// any other non-OK response — error.status is number
}
throw error
}
body stays unknown on every class. Precise per-operation error body
types would need a union type derived from each operation's declared error responses — a
named non-goal, since one operation can declare a different body shape per status.418 still gets
plain HttpError for it — the fixed set does not grow to match your document.