Skip to main content

FetchResponseError

An error representing a response with a failure status code (4XX or 5XX).

constructor()

Creates a new FetchResponseError instance.

new FetchResponseError<Schema, Method, Path>(request, response);

Arguments:

  1. request: FetchRequest

    The fetch request that caused the error.

  2. response: FetchResponse

    The fetch response that caused the error.

Type arguments:

  1. Schema: HttpSchema

    The HTTP schema used for the fetch instance.

  2. Method: string

    The HTTP method of the request that caused the error. Must be one of the methods of the path defined in the schema.

  3. Path: string

    The path of the request that caused the error. Must be one of the paths defined in the schema.

import { HttpSchema } from '@zimic/http';
import { createFetch } from '@zimic/fetch';

interface User {
id: string;
username: string;
}

type Schema = HttpSchema<{
'/users/:userId': {
GET: {
response: {
200: { body: User };
404: { body: { message: string } };
};
};
};
}>;

const fetch = createFetch<Schema>({
baseURL: 'http://localhost:3000',
});

const response = await fetch(`/users/${userId}`, {
method: 'GET',
});

if (!response.ok) {
console.log(response.error); // FetchResponseError<Schema, 'GET', '/users'>
}

error.toObject()

Converts the error into a plain object. This method is useful for serialization, debugging, and logging purposes.

error.toObject();
error.toObject(options);

Arguments:

  1. options: FetchResponseErrorObjectOptions

    The options for converting the error. By default, the body of the request and response will not be included.

    • includeRequestBody: boolean | undefined (default false)

      Whether to include the body of the request in the plain object.

    • includeResponseBody: boolean | undefined (default false)

      Whether to include the body of the response in the plain object.

Returns: FetchResponseErrorObject

A plain object representing this error. If options.includeRequestBody or options.includeResponseBody is true, the body of the request and response will be included, respectively, and the return is a Promise. Otherwise, the return is the plain object itself without the bodies.

const fetch = createFetch<Schema>({
baseURL: 'http://localhost:3000',
});

const response = await fetch(`/users/${userId}`, {
method: 'GET',
});

if (!response.ok) {
const errorObject = response.error.toObject();
console.log(errorObject);
// { name: 'FetchResponseError', message: '...', request: { ... }, response:{ ... } }

const errorObjectWithBodies = await response.error.toObject({
includeRequestBody: true,
includeResponseBody: true,
});
console.log(errorObjectWithBodies);
// { name: 'FetchResponseError', message: '...', request: { ... }, response:{ ... } }
}

If included, the bodies are parsed automatically based on the content-type header of the request and response.

content-typeParsed as
application/jsonJSON (object)
application/xmlstring
application/x-www-form-urlencodedHttpSearchParams
application/* (others)Blob
multipart/form-dataHttpFormData
multipart/* (others)Blob
text/*string
image/*Blob
audio/*Blob
font/*Blob
video/*Blob
*/* (others)JSON (object) if possible, otherwise Blob
NOTE: Already used bodies

If the body of the request or response has already been used (e.g., read with response.json()), it will not be included in the plain object, even if options.includeRequestBody or options.includeResponseBody is true. This will be flagged with a warning in the console.

If you access a body before calling error.toObject(), consider reading it from a cloned request or response with request.clone() or response.clone(), respectively.

const request = new fetch.Request(`/users/${userId}`, {
method: 'POST',
body: JSON.stringify({ ... }),
});

// Reading the body from a cloned request:
const requestBody = await request.clone().json();
console.log(requestBody);

const response = await fetch(request);

// Reading the body from a cloned response:
const responseBody = await response.clone().json();
console.log(responseBody);

if (!response.ok) {
const errorObject = await response.error.toObject({
includeRequestBody: true,
includeResponseBody: true,
});
console.log(errorObject);
}

Alternatively, you can disable the warning by including each body conditionally based on request.bodyUsed and response.bodyUsed.

// Include the bodies only if available:
const errorObject = await response.error.toObject({
includeRequestBody: !response.error.request.bodyUsed,
includeResponseBody: !response.error.response.bodyUsed,
});

Related: