Коды ошибок и обработка

Справочник кодов SdkError и AjaxError, выбрасываемых SDK, плюс коды ошибок REST Bitrix24, которые через них проявляются.

Обзор

SDK выбрасывает ошибки через два связанных класса:

  • SdkError — выбрасывается самим кодом SDK (валидация, конфигурация, устаревшие пути, внутренние инварианты). Всегда несёт code, status (HTTP-подобный) и необязательный originalError.
  • AjaxError extends SdkError — выбрасывается, когда HTTP-вызов к Bitrix24 завершается неудачей. Добавляет requestInfo (method, requestId, параметры запроса), чтобы вы могли сопоставлять с логами на стороне портала. Начиная с v1.1.2 (#39), requestInfo не включает полный URL запроса, а поля с учётными данными внутри params редактируются — цель в том, чтобы секреты вебхуков не попадали в вывод toJSON() / toString().

Методы, которые не выбрасывают исключения — Call, CallList, Batch, BatchByChunk — сообщают о сбоях через Result/AjaxResult: проверяйте .isSuccess и читайте .getErrorMessages(). FetchList, напротив, выбрасывает исключение при сбое (генератор не может завершиться частично).

import { SdkError, AjaxError } from '@bitrix24/b24jssdk'

try {
  // …вызовы SDK
}
catch (error) {
  if (error instanceof AjaxError) {
    // сетевой / портальный сбой; error.code — это код Bitrix24
    console.error(error.code, error.status, error.requestInfo?.method, error.requestInfo?.requestId)
  }
  else if (error instanceof SdkError) {
    // проблема на стороне SDK; error.code начинается с JSSDK_
    console.error(error.code, error.status)
  }
  else {
    throw error
  }
}

Коды SdkError, выбрасываемые SDK

Коды — стабильные строки; сопоставляйте по ним, не парсите сообщения.

КодСтатусГде выбрасываетсяЧто означает
JSSDK_CORE_B24_NOT_INIT500геттеры AbstractB24Вы вызвали метод на экземпляре B24, конструктор которого не завершился. Для B24Frame дождитесь initializeB24Frame(); для B24Hook URL был некорректным.
JSSDK_CORE_B24_HTTP_V2_NOT_INIT500getHttpClient(ApiVersion.v2)HTTP-клиент v2 не был создан (обычно ошибка конфигурации).
JSSDK_CORE_B24_HTTP_V3_NOT_INIT500getHttpClient(ApiVersion.v3)То же, для v3.
JSSDK_CORE_B24_API_WRONG500getHttpClientЗапрошена неизвестная ApiVersion.
JSSDK_CORE_DEPRECATED_METHODтолько логгерНе выбрасывается — выводится как warning-лог при вызове устаревших callMethod / callBatch / callListMethod / fetchListMethod / callBatchByChunk. Перейдите на b24.actions.v2.* / v3.*.
JSSDK_CORE_METHOD_AVAILABLE_IN_API_V3только логгерПредупреждение, выводимое CallV2.make(), когда метод также существует в v3. Перейдите, когда сможете.
JSSDK_CORE_METHOD_NOT_SUPPORT_IN_API_V3500CallV3.make(), BatchV3.make(), AjaxResult.getNext()Вы попросили v3 выполнить метод, которого нет в поверхности v3. Используйте v2 или разбейте батч по версиям API.
JSSDK_CORE_B24_FETCH_LIST_METHOD_API_V2500генератор FetchListV2.make()Нижележащий запрос страницы завершился неудачей; генератор останавливается. Оборачивайте for await в try/catch.
JSSDK_CORE_B24_FETCH_LIST_METHOD_API_V3500генератор FetchListV3.make()То же, для v3.
JSSDK_VERSION_MANAGER_NOT_DETECT_FOR_METHODversionManagerВнутренний — не удалось определить версию API метода. Обычно идёт в паре с одним из кодов выше.
JSSDK_BATCH_TOO_LARGE400HTTP-клиент v2В один батч передано более 50 команд. Используйте BatchByChunk.
JSSDK_BATCH_EMPTY400HTTP-клиент v2Пустой calls.
JSSDK_BATCH_SUB_ERROR500обработка батчаОбёртка для сбоя вложенного вызова внутри батча. Проверьте результат конкретного вызова.
JSSDK_INTERACTION_BATCH_BUILD_STRATEGY_V3_EMPTY_COMMAND400обработка батча v3Отдельная команда в v3-батче была пустой/некорректной.
JSSDK_INTERACTION_BATCH_BUILD_STRATEGY_V3_EMPTY_COMMANDS400обработка батча v3Весь массив commands был пуст.
JSSDK_INTERACTION_BATCH_STRATEGY_V2_EMPTY_COMMANDS400обработка батча v2То же, для v2.
JSSDK_INTERACTION_BATCH_STRATEGY_V2_EMPTY_COMMAND_RESPONSE500обработка батча v2У команды в ответе не было тела — обычно на стороне портала.
JSSDK_INTERACTION_BATCH_EMPTY_PROCESSING_STRATEGY500обработка батчаВнутренний — не удалось найти стратегию.
JSSDK_INTERACTION_BATCH_ROW_FAIL500парсер строки батчаНе удалось разобрать одну строку батча.
JSSDK_INVALID_PARAMS400HTTP-транспортФорма params была отклонена до отправки запроса.
JSSDK_PARAMS_TOO_LARGE413HTTP-транспортСериализованное тело запроса превысило лимит размера. Разбейте вызов.
JSSDK_CALL_ALL_ATTEMPTS_EXHAUSTED500HTTP-транспортПовторы (по умолчанию 3, настраивается через RestrictionParams.maxRetries) исчерпаны до того, как вызов удался.
JSSDK_UNKNOWN_ERROR500разноеЗапасной вариант, когда не подходит более конкретный код.
JSSDK_INTERNAL_ERROR500SdkError.fromExceptionКод по умолчанию при оборачивании неизвестного исключения.
JSSDK_INTERNAL_AJAX_ERROR500AjaxError.fromExceptionКод по умолчанию при оборачивании неизвестной HTTP-ошибки.
JSSDK_CLIENT_SIDE_WARNINGконструктор B24HookПредупреждение при создании B24Hook в браузере — вебхуки раскрывают секрет уровня портала и не должны попадать в клиентские бандлы.

Коды со стороны REST, возвращаемые как AjaxError

Bitrix24 возвращает их в поле error HTTP-ответа. SDK переносит их в AjaxError.code как есть — сопоставляйте по строке.

КодHTTP-статусЗначениеТипичное решение
expired_token401OAuth access token истёк.SDK автообновляет для B24Frame и B24OAuth; для кастомных транспортов — обновите и повторите один раз.
invalid_token401Токен некорректен или отозван.Пользователь должен переавторизоваться (OAuth-флоу); URL вебхука неверен.
AUTHORIZE_ERROR403Вызывающему не разрешено выполнять это действие.Неверный scope у вебхука/приложения, или у пользователя нет права доступа (например, права CRM).
WRONG_AUTH_TYPE403Тип токена не соответствует endpoint (например, вебхук использован там, где требуется OAuth).Используйте правильный метод аутентификации для endpoint.
QUERY_LIMIT_EXCEEDED503Достигнут rate limit (на секунду / на метод).Уже обрабатывается встроенным RateLimiter — увеличивайте restrictionParams.maxConcurrent только если понимаете цену.
OVERLOAD_LIMIT503Сброс нагрузки на уровне всего портала.Сделайте паузу, повторите через несколько секунд. AdaptiveDelayer SDK уже это делает.
ERROR_METHOD_NOT_FOUND400Неверное имя метода, или у приложения нет scope, чтобы его видеть.Проверьте написание; сверьте SCOPE из app.info с требуемым scope метода.
INVALID_REQUEST400Плохие параметры (отсутствует обязательное поле, неверный тип).Проверьте error.message — описание Bitrix24 называет проблемное поле.

Это не исчерпывающий список — полный список по методам Bitrix24 публикует на apidocs.bitrix24.ru. Всё, что здесь не перечислено, проходит как есть в AjaxError.code.

Паттерны обработки

Отличить баги SDK от сбоев на стороне портала

AjaxError наследует SdkError, поэтому располагайте проверки instanceof от частного к общему:

// @check-ignore: top-level try/catch with return, not valid at module scope

import { AjaxError, SdkError } from '@bitrix24/b24jssdk'

try {
  await $b24.actions.v2.call.make({ method: 'crm.deal.get', params: { id: 1 } })
}
catch (error) {
  if (error instanceof AjaxError) {
    // Сторона портала: error.code — это код Bitrix24 (например, expired_token)
    if (error.code === 'expired_token') return refreshAndRetry()
    if (error.code === 'AUTHORIZE_ERROR') return showPermissionDenied()
    throw error
  }
  if (error instanceof SdkError) {
    // Сторона SDK: error.code начинается с JSSDK_
    throw error // это ошибки программиста, показывайте их
  }
  throw error
}

// @check-ignore: top-level try/catch with return, not valid at module scope

import { AjaxError, SdkError } from '@bitrix24/b24jssdk'

try {
  await $b24.actions.v3.call.make({ method: 'crm.deal.get', params: { id: 1 } })
}
catch (error) {
  if (error instanceof AjaxError) {
    // Сторона портала: error.code — это код Bitrix24 (например, expired_token)
    if (error.code === 'expired_token') return refreshAndRetry()
    if (error.code === 'AUTHORIZE_ERROR') return showPermissionDenied()
    throw error
  }
  if (error instanceof SdkError) {
    // Сторона SDK: error.code начинается с JSSDK_
    throw error // это ошибки программиста, показывайте их
  }
  throw error
}

Используйте isSuccess для невыбрасывающих методов

Call, CallList, Batch, BatchByChunk возвращают Result / AjaxResult вместо выброса исключения:

// @check-ignore: top-level return in callList error-handling illustration

const response = await $b24.actions.v2.callList.make({ /* … */ })
if (!response.isSuccess) {
  console.error(response.getErrorMessages().join('; '))
  return
}
const items = response.getData()

// @check-ignore: top-level return in callList error-handling illustration

const response = await $b24.actions.v3.callList.make({ /* … */ })
if (!response.isSuccess) {
  console.error(response.getErrorMessages().join('; '))
  return
}
const items = response.getData()

Для батчей с isHaltOnError: false isSuccess становится false при любом сбое вложенного вызова, но getData() всё равно содержит успешные записи. Итерируйте и проверяйте .isSuccess по каждой строке, если нужно знать, какие вызовы прошли.

Оборачивайте for await в try/catch для FetchList

// @check-ignore: top-level for-await in fetchList error-handling illustration

try {
  for await (const chunk of $b24.actions.v2.fetchList.make({ /* … */ })) {
    await persist(chunk)
  }
}
catch (error) {
  if (
    error instanceof SdkError
    && error.code === 'JSSDK_CORE_B24_FETCH_LIST_METHOD_API_V2'
  ) {
    // запрос страницы завершился неудачей; сохранённые до этого момента чанки всё ещё валидны
    return resumeFromLastSavedId()
  }
  throw error
}

// @check-ignore: top-level for-await in fetchList error-handling illustration

try {
  for await (const chunk of $b24.actions.v3.fetchList.make({ /* … */ })) {
    await persist(chunk)
  }
}
catch (error) {
  if (
    error instanceof SdkError
    && error.code === 'JSSDK_CORE_B24_FETCH_LIST_METHOD_API_V3'
  ) {
    // запрос страницы завершился неудачей; сохранённые до этого момента чанки всё ещё валидны
    return resumeFromLastSavedId()
  }
  throw error
}

Решите, что повторять

Условие ошибкиБезопасно повторять?
QUERY_LIMIT_EXCEEDED, OVERLOAD_LIMITДа — встроенный лимитер уже это делает.
expired_token (Frame/OAuth)Да — уже автоматически. Для кастомных транспортов: обновите, повторите один раз.
invalid_token, AUTHORIZE_ERROR, WRONG_AUTH_TYPEНет — нужно вмешательство человека (переавторизация, исправление scope).
ERROR_METHOD_NOT_FOUND, INVALID_REQUESTНет — запрос некорректен; повтор даст ту же ошибку.
Сеть / 5xx без конкретного кодаДа — но только через границу JSSDK_CALL_ALL_ATTEMPTS_EXHAUSTED; увеличьте restrictionParams.maxRetries, если нужно больше попыток.

См. также

  • Выбор метода — подбирает правильный примитив до того, как вам придётся читать эту страницу.
  • Система ограничений — конфигурация rate limit, времени операций и адаптивной задержки.
  • AjaxResult — полная поверхность payload (isSuccess, getData, getErrorMessages). Пейджинговые хелперы только для v2 — isMore, hasMore, getNext, fetchNext и getTotal — устарели и намечены к удалению в 2.0.0; используйте вместо них b24.actions.v{2,3}.callList.make или fetchList.make. getNext() продолжает выбрасывать JSSDK_CORE_METHOD_NOT_SUPPORT_IN_API_V3 на клиентах v3.