Error Handling
Rezo throws RezoError instances for all failures: network errors, HTTP errors, timeouts, proxy issues, TLS problems, and more. Each error carries a structured error code, boolean classification flags, and the original request configuration.
Basic Usage
import rezo, { RezoError } from 'rezo';
try {
const response = await rezo.get('https://api.example.com/data');
} catch (error) {
if (error instanceof RezoError) {
console.log(error.code); // "REZ_HTTP_ERROR"
console.log(error.status); // 404
console.log(error.message); // "Request failed with status code 404"
console.log(error.suggestion); // "Check the status code and response body..."
}
} RezoError Properties
code
RezoErrorCodeString — The error code identifying the failure type. Provides full IDE autocomplete for all known codes while still accepting unknown OS/runtime error codes.
if (error.code === 'ECONNREFUSED') {
console.log('Server is down');
}
// Also available via the enum
import { RezoErrorCode } from 'rezo';
if (error.code === RezoErrorCode.CONNECTION_REFUSED) {
console.log('Server is down');
} config
RezoConfig — The request configuration that produced the error.
console.log(error.config.url);
console.log(error.config.method); request
RezoHttpRequest | undefined — The request object, when available.
response
RezoResponse<T> | undefined — The server response, when available (only for HTTP errors where the server responded).
if (error.response) {
console.log(error.response.status); // 403
console.log(error.response.data); // Error body from server
console.log(error.response.headers); // Response headers
} status
number | undefined — The HTTP status code. Only defined when the error includes a response.
if (error.status === 429) {
console.log('Rate limited, retry later');
} statusText
string | undefined — The HTTP status text (e.g., "Not Found"). Only defined when the error includes a response.
suggestion
string — A human-readable recovery suggestion for the error code. Useful for logging and debugging.
console.log(error.suggestion);
// "Verify the server is running and accessible. Check firewall rules..." Boolean Classification Flags
Every RezoError carries boolean flags for fast classification. These are non-enumerable (they do not clutter console.log output) but are always accessible.
isTimeout
true when the error is a timeout: ETIMEDOUT, UND_ERR_CONNECT_TIMEOUT, UND_ERR_HEADERS_TIMEOUT, UND_ERR_REQUEST_TIMEOUT, ERR_TLS_HANDSHAKE_TIMEOUT, REZ_PROXY_TIMEOUT.
if (error.isTimeout) {
console.log('Request timed out, consider increasing timeout');
} isAborted
true when the request was explicitly aborted: ABORT_ERR, UND_ERR_ABORTED.
if (error.isAborted) {
console.log('Request was cancelled');
} isNetworkError
true for low-level network failures: ECONNREFUSED, ECONNRESET, ENOTFOUND, EAI_AGAIN, EPIPE, EHOSTUNREACH, ENETUNREACH, UND_ERR_SOCKET.
if (error.isNetworkError) {
console.log('Network problem, check connectivity');
} isHttpError
true when the server responded with a non-successful status code (REZ_HTTP_ERROR). The response property is always set for HTTP errors.
if (error.isHttpError) {
console.log(`Server returned ${error.status}: ${error.response?.data}`);
} isProxyError
true for proxy-related failures: REZ_PROXY_CONNECTION_FAILED, REZ_PROXY_AUTHENTICATION_FAILED, REZ_PROXY_TARGET_UNREACHABLE, REZ_PROXY_ERROR, REZ_PROXY_TIMEOUT, REZ_PROXY_INVALID_PROTOCOL, REZ_PROXY_INVALID_HOSTPORT.
if (error.isProxyError) {
console.log('Proxy failure, try a different proxy');
} isSocksError
true for SOCKS proxy failures: REZ_SOCKS_CONNECTION_FAILED, REZ_SOCKS_AUTHENTICATION_FAILED, REZ_SOCKS_TARGET_CONNECTION_FAILED, REZ_SOCKS_PROTOCOL_ERROR, REZ_SOCKS_UNSUPPORTED_VERSION.
if (error.isSocksError) {
console.log('SOCKS proxy issue');
} isTlsError
true for TLS/SSL failures: EPROTO, ERR_TLS_CERT_ALTNAME_INVALID, ERR_TLS_HANDSHAKE_TIMEOUT, ERR_TLS_INVALID_PROTOCOL_VERSION, ERR_TLS_RENEGOTIATION_DISABLED, ERR_TLS_CERT_SIGNATURE_ALGORITHM_UNSUPPORTED, CERT_HAS_EXPIRED, UNABLE_TO_VERIFY_LEAF_SIGNATURE, SELF_SIGNED_CERT_IN_CHAIN, DEPTH_ZERO_SELF_SIGNED_CERT.
if (error.isTlsError) {
console.log('Certificate or TLS problem');
} isRetryable
true when the error is safe to retry: all timeout codes plus ECONNRESET, ECONNREFUSED, EAI_AGAIN, REZ_RATE_LIMITED, and REZ_HTTP_ERROR.
if (error.isRetryable) {
// Safe to retry this request
} Static Factories
RezoError provides static factory methods for creating specific error types. These are primarily used internally by adapters but are available for testing and custom adapter development.
RezoError.createHttpError(statusCode, config, request?, response?)
Creates an HTTP error with status code, method, URL, and redirect chain information.
const error = RezoError.createHttpError(404, config, request, response);
// error.code === 'REZ_HTTP_ERROR'
// error.status === 404
// error.statusText === 'Not Found' RezoError.createNetworkError(message, code, config, request?)
Creates a network-level error with a specific error code.
const error = RezoError.createNetworkError('Connection failed', 'ECONNREFUSED', config); RezoError.createTimeoutError(message, config, request?)
Creates a timeout error with code ETIMEDOUT.
const error = RezoError.createTimeoutError('Request timed out after 5000ms', config); RezoError.createAbortError(message, config, request?)
Creates an abort error with code ABORT_ERR.
RezoError.createParsingError(message, config, request?)
Creates a JSON parsing error with code REZ_INVALID_JSON.
RezoError.createDecompressionError(message, config, request?, response?)
Creates a decompression error with code REZ_DECOMPRESSION_ERROR.
RezoError.createDownloadError(message, config, request?, response?)
Creates a download failure with code REZ_DOWNLOAD_FAILED.
RezoError.createUploadError(message, config, request?, response?)
Creates an upload failure with code REZ_UPLOAD_FAILED.
RezoError.createStreamError(message, config, request?, response?)
Creates a stream error with code REZ_STREAM_ERROR.
RezoError.createRedirectError(message, config, request?, response?)
Creates a redirect error with code REZ_MISSING_REDIRECT_LOCATION.
RezoError.createProxyError(code, config, request?)
Creates a proxy error. The code must be a valid proxy error code; invalid codes fall back to REZ_PROXY_ERROR.
RezoError.createSocksError(code, config, request?)
Creates a SOCKS proxy error. Invalid codes fall back to REZ_SOCKS_CONNECTION_FAILED.
RezoError.createTlsError(code, config, request?)
Creates a TLS error. Invalid codes fall back to EPROTO.
RezoError.createRateLimitError(config, request?, response?)
Creates a rate-limit error with code REZ_RATE_LIMITED and status 429.
RezoError.fromError(error, config, request?, response?)
Wraps any Error instance into a RezoError, preserving the original error as cause and extracting OS-level properties (syscall, hostname, port, address).
try {
// some operation
} catch (err) {
throw RezoError.fromError(err, config);
} Type Guard
isRezoError(error)
A type guard function that checks if a value is a RezoError. Works across module boundaries where instanceof may fail.
import { isRezoError } from 'rezo';
try {
await rezo.get('https://api.example.com/data');
} catch (error) {
if (isRezoError(error)) {
// error is typed as RezoError
console.log(error.code);
}
} Also available as a static method:
RezoError.isRezoError(error); Serialization
toJSON()
Returns a clean JSON representation with only defined values. Includes: name, message, code, method, url, finalUrl, status, statusText, urls, and cause.
console.log(JSON.stringify(error.toJSON(), null, 2));
// {
// "name": "RezoError",
// "message": "Request failed with status code 404",
// "code": "REZ_HTTP_ERROR",
// "method": "GET",
// "url": "https://api.example.com/missing",
// "status": 404,
// "statusText": "Not Found"
// } toString()
Returns a concise string representation.
console.log(error.toString());
// "RezoError: Request failed with status code 404 [REZ_HTTP_ERROR]" getFullDetails()
Returns a multi-line diagnostic string with all available information, including the redirect chain and recovery suggestion.
console.log(error.getFullDetails());
// RezoError: Request failed with status code 404
// Code: REZ_HTTP_ERROR
// Method: GET
// URL: https://api.example.com/missing
// HTTP Status: 404 Not Found
//
// Suggestion: Check the status code and response body for more details about the error. ERROR_INFO Reference
The ERROR_INFO map contains metadata for every known error code. Each entry provides a human-readable message, a detailed explanation, and a recovery suggestion.
Network and OS Errors
| Code | Message |
|---|---|
ECONNREFUSED | Connection Refused |
ECONNRESET | Connection Reset |
ECONNABORTED | Connection Aborted |
ETIMEDOUT | Connection Timeout |
ESOCKETTIMEDOUT | Socket Timeout |
ENOTFOUND | DNS Lookup Failed |
EAI_AGAIN | Temporary DNS Failure |
EHOSTUNREACH | Host Unreachable |
ENETUNREACH | Network Unreachable |
EPIPE | Broken Pipe |
HTTP Errors
| Code | Message |
|---|---|
REZ_HTTP_ERROR | HTTP Error |
REZ_REDIRECT_DENIED | Redirect Denied |
REZ_MAX_REDIRECTS_EXCEEDED | Maximum Redirects Exceeded |
REZ_REDIRECT_CYCLE_DETECTED | Redirect Cycle Detected |
REZ_MISSING_REDIRECT_LOCATION | Missing Redirect Location |
REZ_DECOMPRESSION_ERROR | Decompression Error |
REZ_RATE_LIMITED | Rate Limited |
REZ_INVALID_JSON | Invalid JSON Response |
Stream and Transfer Errors
| Code | Message |
|---|---|
REZ_DOWNLOAD_FAILED | Download Failed |
REZ_UPLOAD_FAILED | Upload Failed |
REZ_STREAM_ERROR | Stream Error |
REZ_BODY_TOO_LARGE | Request Body Too Large |
REZ_RESPONSE_TOO_LARGE | Response Too Large |
ERR_STREAM_DESTROYED | Stream Destroyed |
ERR_STREAM_PREMATURE_CLOSE | Premature Stream Close |
Proxy Errors
| Code | Message |
|---|---|
REZ_PROXY_CONNECTION_FAILED | Proxy Connection Failed |
REZ_PROXY_AUTHENTICATION_FAILED | Proxy Authentication Failed |
REZ_PROXY_TARGET_UNREACHABLE | Proxy Target Unreachable |
REZ_PROXY_ERROR | Proxy Error |
REZ_PROXY_TIMEOUT | Proxy Timeout |
REZ_PROXY_INVALID_PROTOCOL | Invalid Proxy Protocol |
REZ_PROXY_INVALID_HOSTPORT | Invalid Proxy Configuration |
REZ_NO_PROXY_AVAILABLE | No Proxy Available |
SOCKS Proxy Errors
| Code | Message |
|---|---|
REZ_SOCKS_CONNECTION_FAILED | SOCKS Proxy Connection Failed |
REZ_SOCKS_AUTHENTICATION_FAILED | SOCKS Proxy Authentication Failed |
REZ_SOCKS_TARGET_CONNECTION_FAILED | SOCKS Proxy Target Unreachable |
REZ_SOCKS_PROTOCOL_ERROR | SOCKS Protocol Error |
REZ_SOCKS_UNSUPPORTED_VERSION | SOCKS Version Not Supported |
TLS / SSL Errors
| Code | Message |
|---|---|
EPROTO | Protocol Error |
ERR_TLS_CERT_ALTNAME_INVALID | Certificate Hostname Mismatch |
ERR_TLS_HANDSHAKE_TIMEOUT | TLS Handshake Timeout |
ERR_TLS_INVALID_PROTOCOL_VERSION | TLS Protocol Version Mismatch |
ERR_TLS_RENEGOTIATION_DISABLED | TLS Renegotiation Disabled |
ERR_TLS_CERT_SIGNATURE_ALGORITHM_UNSUPPORTED | Unsupported Certificate Signature |
CERT_HAS_EXPIRED | Certificate Expired |
UNABLE_TO_VERIFY_LEAF_SIGNATURE | Certificate Verification Failed |
SELF_SIGNED_CERT_IN_CHAIN | Self-Signed Certificate |
DEPTH_ZERO_SELF_SIGNED_CERT | Self-Signed Certificate (No Chain) |
Timeout and Abort Errors
| Code | Message |
|---|---|
UND_ERR_CONNECT_TIMEOUT | Connect Timeout |
UND_ERR_HEADERS_TIMEOUT | Headers Timeout |
UND_ERR_REQUEST_TIMEOUT | Request Timeout |
ABORT_ERR | Request Aborted |
UND_ERR_ABORTED | Request Aborted |
ERR_ABORTED | Request Aborted |
Validation Errors
| Code | Message |
|---|---|
ERR_INVALID_URL | Invalid URL |
ERR_INVALID_PROTOCOL | Invalid URL Protocol |
ERR_INVALID_ARG_TYPE | Invalid Argument Type |
REZ_FILE_PERMISSION_ERROR | File Permission Error |
Other
| Code | Message |
|---|---|
REZ_UNKNOWN_ERROR | Unknown Error |
ERR_HTTP_HEADERS_SENT | Headers Already Sent |
UND_ERR_SOCKET | Socket Error |
UND_ERR_INFO | Invalid Request Info |
RezoErrorCode Enum
For type-safe code comparisons, use the RezoErrorCode enum:
import { RezoErrorCode } from 'rezo';
switch (error.code) {
case RezoErrorCode.CONNECTION_REFUSED:
console.log('Server is not running');
break;
case RezoErrorCode.DNS_LOOKUP_FAILED:
console.log('Invalid hostname');
break;
case RezoErrorCode.HTTP_ERROR:
console.log(`HTTP ${error.status}`);
break;
case RezoErrorCode.PROXY_CONNECTION_FAILED:
console.log('Proxy is down');
break;
case RezoErrorCode.CERTIFICATE_EXPIRED:
console.log('SSL certificate has expired');
break;
} Practical Patterns
Categorized Error Handler
try {
const response = await rezo.get('https://api.example.com/data');
} catch (error) {
if (!isRezoError(error)) throw error;
if (error.isHttpError) {
switch (error.status) {
case 401: return redirectToLogin();
case 403: return showForbidden();
case 404: return showNotFound();
case 429: return retryAfterDelay(error);
default: return showServerError(error);
}
}
if (error.isTimeout) {
return showTimeoutMessage();
}
if (error.isNetworkError) {
return showOfflineMessage();
}
if (error.isProxyError || error.isSocksError) {
return rotateProxy();
}
if (error.isTlsError) {
return showCertificateWarning();
}
throw error;
} Logging Errors
catch (error) {
if (isRezoError(error)) {
// Structured log for monitoring
logger.error({
...error.toJSON(),
suggestion: error.suggestion,
retryable: error.isRetryable
});
// Detailed diagnostic for debugging
if (process.env.DEBUG) {
console.error(error.getFullDetails());
}
}
}