Error Handling
Catch FetchError and ValidationError, and handle parsing, abort, and network failures from fetch calls.
fetch throws FetchError for HTTP failures and ValidationError for schema failures. Platform and schema errors can still propagate from native fetch, body parsing, request construction, or the validator itself.
| Error | Import path | Thrown when |
|---|---|---|
FetchError |
fetch |
The response is not ok and throwOnFetchError is true (default). |
ValidationError |
validation |
A schema is provided, validation returns issues, and throwOnValidationError is true (default). |
import { FetchError } from "@zap-studio/fetch";
import { ValidationError } from "@zap-studio/validation";
FetchError
Thrown for non-2xx responses before the body is parsed or validated. Its message has the form HTTP <status>: <statusText>.
| Property | Type | Description |
|---|---|---|
status |
number |
HTTP status code from the failing response. |
response |
Response |
Full response object for further inspection (headers, body, …). |
import { api, FetchError } from "@zap-studio/fetch";
import { z } from "zod";
const UserSchema = z.object({ id: z.number(), name: z.string() });
try {
await api.get("https://api.example.com/users/missing", UserSchema);
} catch (error) {
if (error instanceof FetchError) {
console.error(error.status);
console.error(await error.response.text());
} else {
throw error;
}
}
Set throwOnFetchError: false to handle the response manually.
import { $fetch } from "@zap-studio/fetch";
const response = await $fetch("https://api.example.com/users/missing", {
throwOnFetchError: false,
});
if (!response.ok) {
console.error(response.status);
}
ValidationError
Thrown when the response body does not match the provided schema. Its message is a JSON string of the issues.
| Property | Type | Description |
|---|---|---|
issues |
readonly StandardSchemaV1.Issue[] |
Validation issues reported by the schema. |
import { api } from "@zap-studio/fetch";
import { ValidationError } from "@zap-studio/validation";
import { z } from "zod";
const UserSchema = z.object({ id: z.number(), name: z.string() });
try {
await api.get("https://api.example.com/users/1", UserSchema);
} catch (error) {
if (error instanceof ValidationError) {
console.error(error.issues);
} else {
throw error;
}
}
Set throwOnValidationError: false to receive the Standard Schema result object instead.
import { api } from "@zap-studio/fetch";
import { z } from "zod";
const UserSchema = z.object({ id: z.number(), name: z.string() });
const result = await api.get("https://api.example.com/users/1", UserSchema, {
throwOnValidationError: false,
});
if (result.issues) {
console.error(result.issues);
}
See Validation for the full validation flow.
Other Throwable Errors
Calls can also reject with:
TypeError— bothbodyandjsonprovided, invalid headers or search params, request construction failure, JSON request serialization failure, network failure, or a response body read failure.SyntaxError— a schema is provided andresponse.json()cannot parse the body.DOMException— the request or response body read is aborted (AbortError).- Any error thrown or rejected by the provided Standard Schema validator.
Exhaustive Handling
Catch package-specific errors first, then rethrow unknown failures.
import { api, FetchError } from "@zap-studio/fetch";
import { ValidationError } from "@zap-studio/validation";
import { z } from "zod";
const UserSchema = z.object({ id: z.number(), name: z.string() });
async function loadUser(id: string) {
try {
const user = await api.get(`https://api.example.com/users/${id}`, UserSchema);
return { ok: true as const, user };
} catch (error) {
if (error instanceof FetchError) {
return { ok: false as const, reason: "http", status: error.status };
}
if (error instanceof ValidationError) {
return { ok: false as const, reason: "validation", issues: error.issues };
}
throw error;
}
}