Skip to content

Advanced Usage

Tree-Shaking with the Errors Subpath

The main entry (@pbpeterson/typed-fetch) includes all 40 error classes because typedFetch needs them at runtime. For consumers who only need specific error classes (e.g., for instanceof checks in their own code), import from the ./errors subpath:

typescript
// Tree-shakeable — only pulls NotFoundError + BaseHttpError (~1KB)
import { NotFoundError } from '@pbpeterson/typed-fetch/errors';

// Direct file import
import { NotFoundError } from '@pbpeterson/typed-fetch/errors/not-found-error';

Using statusCodeErrorMap

The exported statusCodeErrorMap lets you look up error classes by status code or build custom error handling:

typescript
import { statusCodeErrorMap } from '@pbpeterson/typed-fetch';

const ErrorClass = statusCodeErrorMap.get(404);
if (ErrorClass) {
  console.log(ErrorClass.name);       // "NotFoundError"
  console.log(ErrorClass.status);     // 404
  console.log(ErrorClass.statusText); // "Not Found"
}

Using httpErrors

The httpErrors array contains all 40 error class constructors, useful for iteration:

typescript
import { httpErrors } from '@pbpeterson/typed-fetch';

for (const ErrorClass of httpErrors) {
  console.log(`${ErrorClass.status}: ${ErrorClass.statusText}`);
}

Error Response Bodies

All HTTP errors provide access to the response body in multiple formats:

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

const { error } = await typedFetch<User, BadRequestError>('/api/users', {
  method: 'POST',
  body: JSON.stringify(invalidData),
});

if (error && isHttpError(error)) {
  const json = await error.json();
  const text = await error.clone().text();
  const blob = await error.clone().blob();
  const buffer = await error.clone().arrayBuffer();

  // Access response headers
  const contentType = error.headers.get('content-type');
  const retryAfter = error.headers.get('retry-after');

  // Literal status types
  console.log(error.status);     // e.g. 400 (literal, not number)
  console.log(error.statusText); // e.g. "Bad Request" (literal, not string)
  console.log(error.name);       // e.g. "BadRequestError"
}

Network vs HTTP Errors

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

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

if (error) {
  if (isNetworkError(error)) {
    // NetworkError has no status — the request never reached the server
    console.log('Connection failed:', error.message);
  } else if (isHttpError(error)) {
    // BaseHttpError has status, statusText, headers, and body methods
    console.log(`HTTP ${error.status}: ${error.statusText}`);
  }
}

Optional RequestInit

The second parameter is optional and defaults to {}:

typescript
// These are equivalent
await typedFetch<User[]>('/api/users');
await typedFetch<User[]>('/api/users', {});

Released under the MIT License.