Skip to content
rhttp.io

Errors

All error classes are exported from every entry point and form an inheritance hierarchy rooted at HttpError.

Hierarchy

Error
 └── HttpError
      ├── TimeoutError
      └── NetworkError

HttpError

The base error for all HTTP-related failures. Thrown on non-2xx responses.

import { HttpError } from "rhttp.io"; 
 
class HttpError extends Error {
  name: "HttpError";
  status: number;         // HTTP status code
  statusText: string;     // status text
  headers: Record<string, string>;
  data: any;               // parsed response body
  requestId: string;
  durationMs: number;
  url: string;
  options?: any;           // original request options (set by core engine)
}

Handling

import { HttpError } from "rhttp.io";
 
try {
  await http.get("/users");
} catch (error) {
  if (error instanceof HttpError) {
    switch (error.status) {
      case 404:
        console.error("Not found:", error.url);
        break;
      case 401:
        console.error("Unauthorized — redirect to login");
        break;
      default:
        console.error(`HTTP ${error.status}: ${error.statusText}`, error.data);
    }
  }
}

TimeoutError

Thrown when a request exceeds the configured timeout (or when an AbortController is aborted).

import { TimeoutError } from "rhttp.io"; 
 
class TimeoutError extends HttpError {
  name: "TimeoutError";
  status: 408;
  statusText: "Request Timeout";
  data: null;
}

Handling

try {
  await http.get("/slow-endpoint", { timeout: 2_000 });
} catch (error) {
  if (error instanceof TimeoutError) {
    console.error("Timed out after", error.durationMs, "ms");
  }
}

NetworkError

Thrown when the request fails to reach the server (DNS failure, connection refused, CORS error, etc.).

import { NetworkError } from "rhttp.io"; 
 
class NetworkError extends HttpError {
  name: "NetworkError";
  status: 0;
  statusText: "Network Error";
  data: null;
  originalError?: any;   // the underlying Error from fetch()
}

Handling

try {
  await http.get("https://unreachable.example.com");
} catch (error) {
  if (error instanceof NetworkError) {
    console.error("Network failure:", error.originalError);
  }
}

Additional error classes (extensions)

These are exported from the root entry point and are used by the advanced features:

import {
  ValidationError,
  AuthenticationError,
  RateLimitError,
  ConflictError,
} from "rhttp.io"; 
ClassUse case
ValidationErrorResponse validation failures (field, value)
AuthenticationErrorAuth failures with originalError
RateLimitErrorRate limit exceeded (retryAfter, remainingRequests)
ConflictError409 conflicts with conflictingResource

Catching all HTTP errors

Since TimeoutError and NetworkError extend HttpError, a single instanceof HttpError check catches everything the library throws:

import { HttpError } from "rhttp.io";
 
try {
  await http.get("/endpoint");
} catch (error) {
  if (error instanceof HttpError) {
    // Covers 4xx/5xx (HttpError), 408 (TimeoutError), and 0 (NetworkError).
    console.error(`[${error.name}] ${error.status} on ${error.url} (${error.durationMs}ms)`);
  } else {
    // Non-HTTP error — rethrow or handle differently.
    throw error;
  }
}
  • TypesHttpMetrics, HttpResponse, and config types.
  • Retry Logic — how retry interacts with errors.
  • Authentication — refresh interceptor for 401 handling.