Error Handling with Types
In this page:
unknown in Catch Blocks
TypeScript types a caught exception in a catch block as unknown by default, which forces you to narrow it — usually with instanceof Error — before accessing properties like .message safely.
Example: unknown in Catch Blocks
try {
throw new Error("Something failed");
} catch (err: unknown) {
if (err instanceof Error) console.log(err.message);
}
Custom API Errors
A custom API error class extending Error can carry extra typed fields like a status code, letting catch blocks branch on specific error types instead of parsing a generic error message string.
Example: Custom API Errors
class ApiError extends Error {
constructor(message: string, public statusCode: number) {
super(message);
}
}
try {
throw new ApiError("Not found", 404);
} catch (err) {
if (err instanceof ApiError) console.log(err.statusCode);
}
Result Types for API Errors
A Result type — like { ok: true, data: T } | { ok: false, error: E } — makes error handling for API calls explicit in the return type itself, forcing callers to check ok before touching data.
Example: Result Types for API Errors
type Result<T, E> = { ok: true; data: T } | { ok: false; error: E };
function parse(input: string): Result<number, string> {
const n = Number(input);
return isNaN(n) ? { ok: false, error: "Invalid number" } : { ok: true, data: n };
}
const result = parse("42");
if (result.ok) console.log(result.data);
HTTP Error Handling
Handling HTTP errors specifically means checking the response status code and mapping it to a typed error (like distinguishing a 404 from a 500) rather than treating every failed request the same generic way.
Example: HTTP Error Handling
function classify(status: number): string {
if (status === 404) return "Not Found";
if (status >= 500) return "Server Error";
return "Unknown";
}
console.log(classify(404));
Combining Error and Result Types
Combining a Result type with typed custom errors gives you both an explicit success/failure branch and detailed error information inside the failure branch, without relying on throw/catch's untyped exception flow at all.
Example: Combining Error and Result Types
class ApiError extends Error {
constructor(message: string, public statusCode: number) { super(message); }
}
type Result<T> = { ok: true; data: T } | { ok: false; error: ApiError };
function fetchUser(): Result<string> {
return { ok: false, error: new ApiError("Not found", 404) };
}
const result = fetchUser();
if (!result.ok) console.log(result.error.statusCode);
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: