---
title: "Handle errors and rate limits"
description: "Catch typed errors, and see how providers retry rate-limited requests."
canonical_url: "https://docs-oquac2tli-poetry.vercel.app/guides/errors"
---
# Handle errors and rate limits

> Catch typed errors, and see how providers retry rate-limited requests.

Failed requests reject with a typed error. All of them extend `ForgeError`, so you can catch the base class and narrow with `instanceof`:

```ts
import { ForgeError, RateLimitedError, TokenRevokedError } from 'forges'

try {
  await gh.threads.close(thread.ref)
}
catch (error) {
  if (error instanceof RateLimitedError) {
    console.warn(`Rate limited until ${error.resetAt?.toISOString()}`)
  }
  else if (error instanceof TokenRevokedError) {
    await askForNewToken()
  }
  else if (error instanceof ForgeError) {
    console.error(error.forge, error.url, error.message)
  }
  else {
    throw error
  }
}
```

Errors carry `forge`, `instance`, `url` and `method` when the failure came from a request. `ForgeApiError` and its subclasses also have `status` and a truncated `body`. The [error reference](https://docs-oquac2tli-poetry.vercel.app/reference/errors) lists every class.

## Rate limits

When a forge rate-limits a request and sets `retry-after` to one minute or less, the provider waits that long and retries once. Pass `onRetry` to log or count these retries. It receives the `url`, the `method` and the `wait` in milliseconds:

```ts
const forge = github({
  auth,
  onRetry: ({ method, url, wait }) =>
    console.warn(`Retrying ${method} ${url} in ${wait} ms`),
}).create()
```

A longer wait, or a second limit, rejects with `RateLimitedError`. `resetAt` tells you when the limit resets, and `secondary` is `true` for an abuse limit that has no request counter.

After a listing, `page.rateLimit` reports the budget the forge sent with the response.

## Unsupported operations

Calling an operation that the forge lacks rejects with `UnsupportedOperationError`. Avoid it with [`can()`](https://docs-oquac2tli-poetry.vercel.app/guides/capabilities).

## Warnings

Some problems don't fail a call. A listing can skip an item it couldn't read, or ignore a filter that the forge lacks. The provider reports these as warnings with a stable `code`, such as `filter_unsupported` or `thread_unreadable`.

Read `warnings` on a page, or on an iterable during or after iteration:

```ts
const threads = gh.threads.list(repo, { sort: 'comments' })

for await (const thread of threads) {
  render(thread)
}

for (const warning of threads.warnings) {
  console.warn(warning.code, warning.message)
}
```

## Timeouts

A request that exceeds the provider's `timeout` rejects with `ForgeTimeoutError`. A request that gets no response, for example because of DNS or TLS failures, rejects with `ForgeNetworkError`.


## Sitemap

See the full [sitemap](https://docs-oquac2tli-poetry.vercel.app/sitemap.md) for all pages.
