import { isError } from "./is.ts" const internalErrorMessages = new Set([ "network error", // Chrome "Failed to fetch", // Chrome "NetworkError when attempting to fetch resource.", // Firefox "The Internet connection appears to be offline.", // Safari 16 "Load failed", // Safari 17+ "Network request failed", // `cross-fetch` "fetch failed", // Undici (Node.js) "terminated", // Undici (Node.js) ]) /** * @description Checks if an error is a network error. * * @see {@link https://github.com/sindresorhus/is-network-error} */ export const errorIsNetworkError = (error: unknown): error is Error => { if (error === null || error === undefined) { return false } if (isError(error) === false) { return false } if (error.name !== "TypeError" || typeof error.message !== "string") { return false } // We do an extra check for Safari 17+ as it has a very generic error message. // Network errors in Safari have no stack. if (error.message === "Load failed") { return error.stack === undefined } return internalErrorMessages.has(error.message) } /** * @description Stringifies an error into a readable format. */ export const errorStringify = (error: unknown): string => { if (isError(error)) { return `${error.name}: ${error.message}` } else { return `${String(error)}` } } /** * @description Converts a value to an Error object. If the value is already an Error, * it is returned as is. Otherwise, a new Error is created with the * stringified value as its message. */ export const toError = (value: unknown): Error => { if (isError(value)) { return value } else { return new Error(String(value)) } }