Never Throws
All errors are returned as values, not exceptions. No more try-catch blocks or unexpected throws.
Inspired by Go's error handling pattern, built on top of the native Fetch API
import { typedFetch, NotFoundError, UnauthorizedError, isHttpError, isNetworkError } from '@pbpeterson/typed-fetch';
interface User {
id: number;
name: string;
email: string;
}
type ExpectedErrors = NotFoundError | UnauthorizedError;
const { response, error } = await typedFetch<User[], ExpectedErrors>('/api/users');
if (error) {
if (error instanceof NotFoundError) {
console.log('Users not found');
} else if (error instanceof UnauthorizedError) {
console.log('Authentication required');
} else if (isNetworkError(error)) {
console.log('Network error:', error.message);
} else {
// Server errors (5xx) are always included
console.log(`HTTP ${error.status}: ${error.statusText}`);
}
} else {
const users = await response.json(); // Type: User[]
console.log('Users:', users);
}Traditional fetch libraries throw exceptions on HTTP errors, making error handling cumbersome and error-prone. typed-fetch follows Go's philosophy of explicit error handling - errors are values, not exceptions.
try {
const response = await fetch('/api/users');
const users = await response.json(); // What if response is 404?
} catch (error) {
// Handle network errors, parsing errors, HTTP errors... all mixed together
}import { typedFetch, NotFoundError, isHttpError } from '@pbpeterson/typed-fetch';
type ExpectedErrors = NotFoundError;
const { response, error } = await typedFetch<User[], ExpectedErrors>('/api/users');
if (error) {
if (error instanceof NotFoundError) {
const details = await error.json<{ message: string }>();
console.log(details.message); // typed!
}
} else {
const users = await response.json(); // Type: User[]
}npm install @pbpeterson/typed-fetchpnpm add @pbpeterson/typed-fetchyarn add @pbpeterson/typed-fetchCheck out the Getting Started guide to learn how to use typed-fetch in your project.