Skip to content

Error Handling

Available Error Classes

All error classes are exported individually for tree-shaking. For details on each status code, see the MDN HTTP Status Reference.

Client Errors (4xx)

ClassStatusStatus Text
BadRequestError400Bad Request
UnauthorizedError401Unauthorized
PaymentRequiredError402Payment Required
ForbiddenError403Forbidden
NotFoundError404Not Found
MethodNotAllowedError405Method Not Allowed
NotAcceptableError406Not Acceptable
ProxyAuthenticationRequiredError407Proxy Authentication Required
RequestTimeoutError408Request Timeout
ConflictError409Conflict
GoneError410Gone
LengthRequiredError411Length Required
PreconditionFailedError412Precondition Failed
RequestTooLongError413Payload Too Large
RequestUriTooLongError414URI Too Long
UnsupportedMediaTypeError415Unsupported Media Type
RequestedRangeNotSatisfiableError416Range Not Satisfiable
ExpectationFailedError417Expectation Failed
ImATeapotError418I'm a teapot
MisdirectedRequestError421Misdirected Request
UnprocessableEntityError422Unprocessable Entity
LockedError423Locked
FailedDependencyError424Failed Dependency
TooEarlyError425Too Early
UpgradeRequiredError426Upgrade Required
PreconditionRequiredError428Precondition Required
TooManyRequestsError429Too Many Requests
RequestHeaderFieldsTooLargeError431Request Header Fields Too Large
UnavailableForLegalReasonsError451Unavailable For Legal Reasons

Server Errors (5xx)

ClassStatusStatus Text
InternalServerError500Internal Server Error
NotImplementedError501Not Implemented
BadGatewayError502Bad Gateway
ServiceUnavailableError503Service Unavailable
GatewayTimeoutError504Gateway Timeout
HttpVersionNotSupportedError505HTTP Version Not Supported
VariantAlsoNegotiatesError506Variant Also Negotiates
InsufficientStorageError507Insufficient Storage
LoopDetectedError508Loop Detected
NotExtendedError510Not Extended
NetworkAuthenticationRequiredError511Network Authentication Required

Network Errors

ClassDescription
NetworkErrorConnection refused, DNS failures, timeouts

Handling Errors with instanceof

typescript
import { typedFetch, NotFoundError, UnauthorizedError, NetworkError } from '@pbpeterson/typed-fetch';

type ExpectedErrors = NotFoundError | UnauthorizedError;
const { response, error } = await typedFetch<User, ExpectedErrors>('/api/users/123');

if (error) {
  if (error instanceof NotFoundError) {
    console.log('User not found');
    const details = await error.json<{ message: string }>();
  } else if (error instanceof UnauthorizedError) {
    console.log('Please log in');
  } else if (error instanceof NetworkError) {
    console.log('Network error:', error.message);
  } else {
    // Server errors (5xx)
    console.log('Server error:', error.statusText);
  }
}

Handling Errors with Type Guards

typescript
import { typedFetch, isHttpError, isNetworkError } from '@pbpeterson/typed-fetch';

const { error } = await typedFetch<User>('/api/users/123');

if (error) {
  if (isHttpError(error)) {
    // error is narrowed to BaseHttpError
    console.log(`${error.name}: ${error.status} ${error.statusText}`);
    const body = await error.json();
  } else if (isNetworkError(error)) {
    // error is narrowed to NetworkError
    console.log('Connection failed:', error.message);
  }
}

Typed Error Bodies

The json<T>() method accepts a type parameter to type the error response body:

typescript
interface ApiError {
  message: string;
  code: string;
  fields?: Record<string, string>;
}

if (error instanceof BadRequestError) {
  const details = await error.json<ApiError>();
  console.log(details.message); // typed as string
  console.log(details.fields);  // typed as Record<string, string> | undefined
}

Static Properties

Access status codes without creating instances:

typescript
import { NotFoundError, BadRequestError } from '@pbpeterson/typed-fetch';

console.log(NotFoundError.status);      // 404 (literal type)
console.log(NotFoundError.statusText);  // "Not Found" (literal type)
console.log(BadRequestError.status);    // 400

Released under the MIT License.