---
title: "Error-handling cookbook"
description: "Demonstrates the four error layers (SdkError / AjaxError / network / soft) and the hardErrorCodes / softErrorCodes / retryOnNetworkError knobs on the restriction manager."
canonical_url: "https://bitrix24.github.io/b24jssdk/docs/examples/error-handling"
last_updated: "2026-06-02"
---
# Error-handling cookbook

> Demonstrates the four error layers (SdkError / AjaxError / network / soft) and the hardErrorCodes / softErrorCodes / retryOnNetworkError knobs on the restriction manager.

## What it does

Shows the canonical error-handling shape for SDK callers:

1. **SdkError** — programming bug (e.g. calling a non-v3 method via `actions.v3.*`).
2. **AjaxError** — REST returned an error (`ERROR_NOT_FOUND`, `INVALID_CREDENTIALS`, `EXPIRED_TOKEN`, `QUERY_LIMIT_EXCEEDED`, …).
3. **Network-level** — `NETWORK_ERROR` / `REQUEST_TIMEOUT`. Critically different for non-idempotent calls.
4. **Soft errors** — codes you've explicitly opted into surfacing via `softErrorCodes` so the call returns `isSuccess: false` instead of throwing.

Also covers `setRestrictionManagerParams` with the new knobs:

- `hardErrorCodes` — extend the SDK's "throw immediately, no retry" list with app-specific codes.
- `softErrorCodes` — extend the "return as soft error in AjaxResult" list.
- `retryOnNetworkError: false` — disable network retry for `*.add` / `*.update` / file uploads to avoid duplicates.

## Stack

Node.js 18+. No external dependencies.

## Environment

```bash
export B24_HOOK='https://your.bitrix24.com/rest/1/secret'
```

## Run

```bash
npx tsx 10-error-handling.ts
```

## Source

[`skills/b24jssdk-recipes/examples/10-error-handling.ts`](https://github.com/bitrix24/b24jssdk/blob/main/skills/b24jssdk-recipes/examples/10-error-handling.ts).

## Notes

- `setRestrictionManagerParams` updates the policy for **all** HTTP clients on this `$b24` instance (both v2 and v3).
- `hardErrorCodes` and `softErrorCodes` are **additive** — built-in lists (auth/fatal codes) are always hard. You can extend, you can't remove.
- For non-idempotent calls, prefer wrapping each call in a `try/finally` that restores `retryOnNetworkError: true` afterwards. The recipe shows this pattern.
- When a network timeout happens for a non-idempotent call, the safe action is **reconcile** (query for the just-created entity by a client-side idempotency tag), not retry.

## Sitemap

See the full [sitemap](/b24jssdk/sitemap.md) for all pages.
