Adapters

Adapters are the detection and normalization layer. Each adapter knows how to recognize a specific error shape and extract its fields into a NormalizedError.

Default adapter chain

When you call normalizeError without specifying adapters, the default chain runs in this order. The first adapter whose canHandle returns true wins.

Default order
// Default adapter chain (used when options.adapters is omitted):
[axiosAdapter, kyAdapter, fetchAdapter, apolloAdapter, nodeHttpAdapter, genericAdapter]

Built-in adapters

Expand each adapter below to see its detection logic, handled error shapes, and example output.

HTTP client

Handles errors thrown by Axios. Detects AxiosError instances by checking isAxiosError, the error name, or the presence of config + request/response properties.

Detection rules

  • isAxiosError === true
  • name === "AxiosError"
  • Has config + (request or response)

Example output

FieldExample value
codeHTTP_503
messageService unavailable. Please retry shortly.
status503
retryabletrue
details{ url: "/api/data", method: "get", ... }

HTTP client

Handles HTTPError and TimeoutError thrown by ky. Detects by checking the error name or the presence of response + request + options.

Detection rules

  • name === "HTTPError" or "TimeoutError"
  • Has response + request + options

Example output

FieldExample value
codeHTTP_503
messageService Unavailable
status503
retryabletrue
details{ url: "/api/data", ... }

Browser fetch

Handles native fetch Response objects and fetch-related errors. Detects Response-like objects (status + statusText/url) and TypeError/AbortError from fetch.

Detection rules

  • Has status + (statusText or url)
  • name === "AbortError" or "TypeError"
  • "fetch" in error message
  • Error with cause.code

Example output

FieldExample value
codeHTTP_503
messageService Unavailable
status503
retryabletrue
details{ url: "http://localhost/api/data", statusText: "Service Unavailable" }

GraphQL

Handles Apollo Client errors and GraphQL error shapes. Detects by checking for graphQLErrors, networkError, or the ApolloError name.

Detection rules

  • Has graphQLErrors array
  • Has networkError
  • name === "ApolloError"

Example output

FieldExample value
codeTOO_MANY_REQUESTS
messageQuota exhausted
status502
retryabletrue
details{ graphQLErrors: [...], networkError: { ... } }

Transport

Handles Node.js transport-level errors such as connection resets, timeouts, and DNS failures. Detects Error instances whose code matches known Node network error codes.

Detection rules

  • Error with code in ECONNRESET, ECONNABORTED, ETIMEDOUT, EAI_AGAIN, ENOTFOUND, ECONNREFUSED, EHOSTUNREACH, EPIPE
  • Error with code starting with UND_ERR_

Example output

FieldExample value
codeECONNRESET
messagesocket hang up
statusnull
retryabletrue
details{ syscall: "read" }

Fallback

Catches everything else. Handles plain Error instances, strings, and arbitrary objects. Always returns true from canHandle, so it should be last in any custom chain.

Detection rules

  • canHandle always returns true

Example output

FieldExample value
codeUNKNOWN_ERROR
messagedatabase connection dropped
statusnull
retryablefalse
detailsnull

Custom adapter chains

Override the default chain by passing your own adapter array. This lets you add domain-specific adapters, remove adapters you don't need, or reorder the chain.

Custom chain
import {
  normalizeError,
  axiosAdapter,
  fetchAdapter,
  genericAdapter
} from "@npmforge/statusforge";

// Only keep adapters you need, in your preferred order
const result = normalizeError(error, {
  adapters: [axiosAdapter, fetchAdapter, genericAdapter]
});

Best practices

Specific before generic
Place your most specific adapters first. The generic adapter matches everything, so it should always be last.
Keep canHandle fast
Avoid async operations or expensive checks in canHandle. It runs synchronously for every adapter in the chain until one matches.
Return partial objects
Your normalize function can return a partial NormalizedError. StatusForge fills in sensible defaults for any fields you omit.