Errors and Retries
Handling errors
Requests reject with a RequestError for network failures, unacceptable status codes, response parsing failures, and validation failures.
import { getErrorResponse, isRequestError } from "api-def";
try {
const response = await fetchHealthCheck.submit({});
console.log(response.data);
} catch (error: unknown) {
if (isRequestError(error)) {
const response = getErrorResponse(error);
console.error(error.code, error.attempts, response?.status);
}
}
Useful error codes include:
request/network-errorfor a failed network operation.request/host-name-not-foundwhen the host cannot be resolved.request/invalid-statuswhen the response status is not acceptable.request/mismatch-response-typewhen the response cannot be parsed as requested.validation/query-validate-error,validation/body-validate-error, andvalidation/response-validate-errorfor schema failures.
The error also includes the attempted request details and the last response when one was available.
Retry configuration
Set retry to a number for a simple retry count, or pass a RetryOptions object for control over retry timing and eligibility:
import { Api, isRequestError } from "api-def";
const API = new Api({
name: "My Backend",
baseUrl: "https://api.example.com",
defaultRequestConfig: {
retry: {
maxAttempts: 3,
minDelay: 200,
maxDelay: 1000,
shouldRetry: (error) => isRequestError(error) && error.response == null,
},
},
});
maxAttempts is the number of retries after the initial attempt. shouldRetry returning true allows the retry; returning false stops retrying and triggers unrecoverableError middleware.
By default, failed requests are retried when retry is enabled. Supply shouldRetry when only particular failures should be retried, such as transient network errors.
Middleware can return { type: "retry" } from the error event to force a retry. Use that carefully because forced retries can loop indefinitely if the middleware never stops returning the result.
Acceptable statuses
Successful responses default to 200 through 299. Override that per endpoint or request:
const redirect = API.endpoint().build({
id: "redirect",
method: "get",
path: "/redirect",
defaultRequestConfig: {
acceptableStatus: [[301, 302], 200],
},
});
Low-level retry helper
The exported retry helper is useful outside request submission:
import { retry } from "api-def";
const result = await retry(
async (bail, attempt) => {
if (attempt === 2) return "ready";
if (attempt > 3) bail(new Error("not ready"));
throw new Error("try again");
},
{ retries: 3, minTimeout: 100, maxTimeout: 500 },
);