A stand-alone types package for Undici HTTP client library
—
Comprehensive error hierarchy covering all HTTP operation failure modes. Undici provides specific error types for different failure scenarios to enable precise error handling and debugging.
/**
* Base class for all Undici errors
*/
class UndiciError extends Error {
name: string;
code: string;
constructor(message?: string);
}Errors related to establishing and maintaining connections.
/**
* Thrown when connection establishment times out
*/
class ConnectTimeoutError extends UndiciError {
name: "ConnectTimeoutError";
code: "UND_ERR_CONNECT_TIMEOUT";
}
/**
* Thrown when socket-level errors occur
*/
class SocketError extends UndiciError {
name: "SocketError";
code: "UND_ERR_SOCKET";
socket: {
localAddress?: string;
localPort?: number;
remoteAddress?: string;
remotePort?: number;
};
}
/**
* Thrown when client is destroyed unexpectedly
*/
class ClientDestroyedError extends UndiciError {
name: "ClientDestroyedError";
code: "UND_ERR_DESTROYED";
}
/**
* Thrown when client is closed unexpectedly
*/
class ClientClosedError extends UndiciError {
name: "ClientClosedError";
code: "UND_ERR_CLOSED";
}
/**
* Thrown when secure proxy connection fails
*/
class SecureProxyConnectionError extends UndiciError {
name: "SecureProxyConnectionError";
code: "UND_ERR_PRX_TLS";
cause?: Error;
}Usage Examples:
import {
Client,
ConnectTimeoutError,
SocketError,
ClientDestroyedError
} from "undici-types";
const client = new Client("https://unreliable.example.com", {
headersTimeout: 5000
});
try {
const response = await client.request({
path: "/api/data",
method: "GET"
});
} catch (error) {
if (error instanceof ConnectTimeoutError) {
console.error("Connection timed out:", error.message);
// Implement retry logic or fallback
} else if (error instanceof SocketError) {
console.error("Socket error:", error.message);
console.error("Connection details:", error.socket);
// Log connection details for debugging
} else if (error instanceof ClientDestroyedError) {
console.error("Client was destroyed:", error.message);
// Create new client instance
}
}Errors related to various timeout scenarios during HTTP operations.
/**
* Thrown when response headers are not received within timeout
*/
class HeadersTimeoutError extends UndiciError {
name: "HeadersTimeoutError";
code: "UND_ERR_HEADERS_TIMEOUT";
}
/**
* Thrown when response body is not received within timeout
*/
class BodyTimeoutError extends UndiciError {
name: "BodyTimeoutError";
code: "UND_ERR_BODY_TIMEOUT";
}
/**
* Thrown when headers exceed maximum size limit
*/
class HeadersOverflowError extends UndiciError {
name: "HeadersOverflowError";
code: "UND_ERR_HEADERS_OVERFLOW";
}
/**
* Thrown when response size exceeds maximum limit
*/
class ResponseExceededMaxSizeError extends UndiciError {
name: "ResponseExceededMaxSizeError";
code: "UND_ERR_RES_EXCEEDED_MAX_SIZE";
maxSize: number;
}Usage Examples:
import {
request,
HeadersTimeoutError,
BodyTimeoutError,
ResponseExceededMaxSizeError
} from "undici-types";
try {
const response = await request("https://slow-api.example.com/large-data", {
headersTimeout: 10000,
bodyTimeout: 30000
});
const data = await response.body.text();
} catch (error) {
if (error instanceof HeadersTimeoutError) {
console.error("Headers not received in time");
// Retry with longer timeout or different endpoint
} else if (error instanceof BodyTimeoutError) {
console.error("Body not received in time");
// Switch to streaming approach or increase timeout
} else if (error instanceof ResponseExceededMaxSizeError) {
console.error(`Response too large: ${error.maxSize} bytes`);
// Use streaming or pagination instead
}
}Errors related to request processing and response handling.
/**
* Thrown when request is aborted
*/
class RequestAbortedError extends UndiciError {
name: "RequestAbortedError";
code: "UND_ERR_ABORTED";
}
/**
* Thrown for general response errors
*/
class ResponseError extends UndiciError {
constructor(
message: string,
code: number,
options: {
headers?: IncomingHttpHeaders | string[] | null;
body?: null | Record<string, any> | string;
}
);
name: "ResponseError";
code: "UND_ERR_RESPONSE";
statusCode: number;
body: null | Record<string, any> | string;
headers: IncomingHttpHeaders | string[] | null;
}
/**
* Thrown for specific HTTP status code errors
*/
class ResponseStatusCodeError extends UndiciError {
constructor(
message?: string,
statusCode?: number,
headers?: IncomingHttpHeaders | string[] | null,
body?: null | Record<string, any> | string
);
name: "ResponseStatusCodeError";
code: "UND_ERR_RESPONSE_STATUS_CODE";
body: null | Record<string, any> | string;
status: number;
statusCode: number;
headers: IncomingHttpHeaders | string[] | null;
}
/**
* Thrown when request retry fails after maximum attempts
*/
class RequestRetryError extends UndiciError {
constructor(
message: string,
statusCode: number,
headers?: IncomingHttpHeaders | string[] | null,
body?: null | Record<string, any> | string
);
name: "RequestRetryError";
code: "UND_ERR_REQ_RETRY";
statusCode: number;
data: {
count: number;
};
headers: Record<string, string | string[]>;
}
/**
* Thrown when request content length doesn't match actual body size
*/
class RequestContentLengthMismatchError extends UndiciError {
name: "RequestContentLengthMismatchError";
code: "UND_ERR_REQ_CONTENT_LENGTH_MISMATCH";
}
/**
* Thrown when response content length doesn't match actual body size
*/
class ResponseContentLengthMismatchError extends UndiciError {
name: "ResponseContentLengthMismatchError";
code: "UND_ERR_RES_CONTENT_LENGTH_MISMATCH";
}Usage Examples:
import {
request,
RequestAbortedError,
ResponseStatusCodeError,
ResponseContentLengthMismatchError
} from "undici-types";
// Request with AbortController
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
try {
const response = await request("https://api.example.com/slow-endpoint", {
signal: controller.signal,
throwOnError: true // Enable automatic status code error throwing
});
const data = await response.body.json();
} catch (error) {
if (error instanceof RequestAbortedError) {
console.error("Request was aborted");
// Handle cancellation
} else if (error instanceof ResponseStatusCodeError) {
console.error(`HTTP ${error.status}: ${error.statusText}`);
console.error("Response body:", error.body);
console.error("Response headers:", error.headers);
// Handle specific status codes
if (error.status === 401) {
// Handle authentication error
} else if (error.status === 429) {
// Handle rate limiting
const retryAfter = error.headers['retry-after'];
console.log(`Retry after: ${retryAfter} seconds`);
}
} else if (error instanceof ResponseContentLengthMismatchError) {
console.error("Response content length mismatch - possible truncated response");
// Retry request or handle partial data
}
}Errors related to input validation and argument checking.
/**
* Thrown when invalid arguments are provided
*/
class InvalidArgumentError extends UndiciError {
name: "InvalidArgumentError";
code: "UND_ERR_INVALID_ARG";
}
/**
* Thrown when invalid return values are encountered
*/
class InvalidReturnValueError extends UndiciError {
name: "InvalidReturnValueError";
code: "UND_ERR_INVALID_RETURN_VALUE";
}
/**
* Thrown when functionality is not supported
*/
class NotSupportedError extends UndiciError {
name: "NotSupportedError";
code: "UND_ERR_NOT_SUPPORTED";
}Usage Examples:
import {
Client,
InvalidArgumentError,
NotSupportedError
} from "undici-types";
try {
// This might throw InvalidArgumentError for invalid URL
const client = new Client("invalid-url");
// This might throw InvalidArgumentError for invalid method
await client.request({
path: "/api/data",
method: "INVALID_METHOD" as any
});
} catch (error) {
if (error instanceof InvalidArgumentError) {
console.error("Invalid argument provided:", error.message);
// Validate inputs before making requests
} else if (error instanceof NotSupportedError) {
console.error("Feature not supported:", error.message);
// Use alternative approach
}
}Errors specific to connection pools and agents.
/**
* Thrown when balanced pool has no available upstreams
*/
class BalancedPoolMissingUpstreamError extends UndiciError {
name: "BalancedPoolMissingUpstreamError";
code: "UND_ERR_BPL_MISSING_UPSTREAM";
}
/**
* Thrown on HTTP parsing errors
*/
class HTTPParserError extends UndiciError {
name: "HTTPParserError";
code: "UND_ERR_PARSER";
bytesParsed: number;
}
/**
* Thrown on informational status code errors (1xx)
*/
class InformationalError extends UndiciError {
name: "InformationalError";
code: "UND_ERR_INFO";
status: number;
statusText: string;
headers: Record<string, string | string[]>;
}Usage Examples:
import {
BalancedPool,
BalancedPoolMissingUpstreamError,
HTTPParserError
} from "undici-types";
// Balanced pool example
const pool = new BalancedPool([]);
try {
await pool.request({
path: "/api/data",
method: "GET"
});
} catch (error) {
if (error instanceof BalancedPoolMissingUpstreamError) {
console.error("No upstreams available in balanced pool");
// Add upstreams or use fallback
pool.addUpstream("https://backup.example.com");
} else if (error instanceof HTTPParserError) {
console.error("HTTP parsing error:", error.message);
console.error("Bytes parsed:", error.bytesParsed);
// Log for debugging malformed responses
}
}Errors related to retry operations.
/**
* Thrown when request retry fails after all attempts
*/
class RequestRetryError extends UndiciError {
name: "RequestRetryError";
code: "UND_ERR_REQ_RETRY";
statusCode: number;
data: {
count: number;
maxCount: number;
};
cause?: Error;
}Usage Examples:
import {
RetryAgent,
Agent,
RequestRetryError
} from "undici-types";
const retryAgent = new RetryAgent(new Agent(), {
retry: 3,
maxTimeout: 30000
});
try {
const response = await retryAgent.request({
origin: "https://unreliable-api.example.com",
path: "/api/data",
method: "GET"
});
} catch (error) {
if (error instanceof RequestRetryError) {
console.error(`Request failed after ${error.data.count} attempts`);
console.error(`Max attempts: ${error.data.maxCount}`);
console.error(`Final status: ${error.statusCode}`);
console.error(`Underlying cause:`, error.cause);
// Handle final failure
// Maybe try alternative endpoint or return cached data
}
}All errors are also available through the errors namespace:
namespace errors {
const UndiciError: typeof UndiciError;
const ConnectTimeoutError: typeof ConnectTimeoutError;
const HeadersTimeoutError: typeof HeadersTimeoutError;
const HeadersOverflowError: typeof HeadersOverflowError;
const BodyTimeoutError: typeof BodyTimeoutError;
const ResponseError: typeof ResponseError;
const ResponseStatusCodeError: typeof ResponseStatusCodeError;
const InvalidArgumentError: typeof InvalidArgumentError;
const InvalidReturnValueError: typeof InvalidReturnValueError;
const RequestAbortedError: typeof RequestAbortedError;
const InformationalError: typeof InformationalError;
const RequestContentLengthMismatchError: typeof RequestContentLengthMismatchError;
const ResponseContentLengthMismatchError: typeof ResponseContentLengthMismatchError;
const ClientDestroyedError: typeof ClientDestroyedError;
const ClientClosedError: typeof ClientClosedError;
const SocketError: typeof SocketError;
const NotSupportedError: typeof NotSupportedError;
const BalancedPoolMissingUpstreamError: typeof BalancedPoolMissingUpstreamError;
const HTTPParserError: typeof HTTPParserError;
const ResponseExceededMaxSizeError: typeof ResponseExceededMaxSizeError;
const RequestRetryError: typeof RequestRetryError;
const SecureProxyConnectionError: typeof SecureProxyConnectionError;
}Usage Examples:
import { errors } from "undici-types";
// Use errors namespace
try {
// Some HTTP operation
} catch (error) {
if (error instanceof errors.ConnectTimeoutError) {
// Handle connection timeout
} else if (error instanceof errors.ResponseStatusCodeError) {
// Handle HTTP status errors
}
}
// Error type checking utility
function isUndiciError(error: unknown): error is UndiciError {
return error instanceof errors.UndiciError;
}
function handleHttpError(error: unknown) {
if (!isUndiciError(error)) {
throw error; // Re-throw non-Undici errors
}
switch (error.code) {
case "UND_ERR_CONNECT_TIMEOUT":
return "Connection timed out - check network connectivity";
case "UND_ERR_RESPONSE_STATUS_CODE":
return `HTTP error: ${(error as errors.ResponseStatusCodeError).status}`;
case "UND_ERR_ABORTED":
return "Request was cancelled";
default:
return `Undici error: ${error.message}`;
}
}Install with Tessl CLI
npx tessl i tessl/npm-undici-types