Перейти к основному содержимому
Версия: 5.21.0

Обработка ошибок и диагностика

Известные ограничения уровня SDK (поведение при разрыве WebSocket, особенности hostname verification) — в Известные ограничения. Пошаговая диагностика — в Troubleshooting.

Справочник ошибок

Какие методы что выбрасывают

МетодУсловиеПоведение
authorize() до init()SDK не инициализированIllegalStateException
getChatFragment() до init() или authorize()SDK не инициализирован или пользователь не авторизованВозвращает null
send(message) без авторизацииПользователь не авторизованВозвращает false
handleFCMMessage() до init()SDK не инициализированIllegalStateException*
init() с пустым providerUidПустая строкаIllegalArgumentException
authorize() с пустым identifierПустой ChatUser.identifierIllegalArgumentException

* При использовании initAsync() вызов откладывается до завершения инициализации (runAfterInit).

Сетевые ошибки (Error)

SDK прозрачно прокидывает HTTP-код ошибки (или внутренний код транспорта) через ChatCenterUIListener.networkErrorReceived(error: Error). Специальной обработки конкретных значений нет — смысл кода определяется вашим бэкендом и стандартом HTTP. Типичные значения:

error.codeСтандартный смыслРекомендуемое действие интегратора
401Не авторизован — токен истёк/невалиденПовторно вызвать authorize() с актуальным токеном
403Доступ запрещёнПроверить providerUid и настройки очереди на стороне edna
500+Серверная ошибкаПоказать пользователю retry, повторить позже

Обратные вызовы ошибок через ChatCenterUIListener

networkErrorReceived

Вызывается при возникновении сетевых ошибок. Объект error имеет тип edna.chatcenter.core.main.Error (не java.lang.Error) и содержит:

  • error.code: Int — числовой код (HTTP-код от сервера или внутренний код WebSocket-транспорта)
  • error.message: String — текстовое описание
  • error.stacktrace: Array<out StackTraceElement>? — стек вызовов (nullable)
import edna.chatcenter.core.main.Error  // обязательно — иначе Kotlin резолвит в kotlin.Error

override fun networkErrorReceived(error: Error) {
Log.e("ChatCenter", "Сетевая ошибка [${error.code}]: ${error.message}")
error.stacktrace?.forEach { element ->
Log.d("ChatCenter", " at $element")
}
}

exceptionReceived

Вызывается при возникновении внутренних исключений SDK. Параметр trace содержит стек вызовов исключения.

override fun exceptionReceived(trace: String) {
Log.e("ChatCenter", "Внутреннее исключение SDK:\n$trace")
}

Практики логирования

Включение логов (ChatLoggerConfig)

val loggerConfig = ChatLoggerConfig(
applicationContext = applicationContext,
logLevel = ChatLogLevel.DEBUG
)

val chatCenterUI = ChatCenterUI(applicationContext, loggerConfig).apply {
init(providerUid = "your_provider_uid", config = chatConfig)
}

Уровни ChatLogLevel: VERBOSE, DEBUG, INFO, WARNING, ERROR, FLUSH. Для production используйте ERROR — это снизит I/O на запись логов в файл.

Сбор логов

  • Logcat — логи печатаются с префиксом тега ELog (например, ELog INFO, ELog ERROR).
  • Файл на устройстве — SDK дублирует логи в файл. Выгрузить можно через View → Tool Windows → Device Explorer в Android Studio.
  • Shake-to-export — при включённом ChatLoggerConfig.shouldShowSendMenu встряхивание устройства открывает экран с логами для экспорта.

LogInterceptor для пользовательской аналитики

Для перехвата и обработки логов SDK можно использовать LogInterceptor. Подробности и пример реализации см. в разделе Расширенные настройки → Логгер.

Граничные случаи

Вызов authorize() до init()

осторожно

Если authorize() вызван до завершения init(), SDK выбросит IllegalStateException. Всегда вызывайте init() в Application.onCreate() и дожидайтесь его завершения перед вызовом authorize().

Повторный вызов init()

Повторный init() допустим, но выполняется строго последовательно и сопровождается частичным сбросом состояния SDK. Обычно init() достаточно вызвать один раз в Application.onCreate() — повторный вызов нужен только при смене ChatConfig (URL/providerUid).

Изменение конфигурации во время активного чата

Менять ChatConfig или тему на лету при открытом ChatFragment не рекомендуется — открытые экраны продолжат работать со старым контекстом. Закройте чат, выполните init(...) с новой конфигурацией и откройте чат заново.

Поведение SDK без сети (offline-режим)

Очередь сообщений

  • При отправке сообщение сохраняется в локальную SQLite со статусом SENDING
  • При активном WebSocket отправляется на сервер; статус переходит в SENTDELIVEREDREAD
  • При ошибке сети статус становится FAILED; пользователю в UI доступен повтор отправки

Полный список статусов в MessageStatus: SENDING, FAILED, SENT, ENQUEUED, DELIVERED, READ.

Поведение при разрыве соединения

Начиная с версии 5.21.0 SDK поддерживает автоматическое переподключение к WebSocket. По умолчанию оно выключено, включается параметром WSConfig.isReconnectEnabled = true — см. Network config.

Если автоматическое переподключение не включено

При isReconnectEnabled = false SDK закрывает сокет после ошибки и сигнализирует через ChatCenterUIListener.networkErrorReceived(). До повторного вызова authorize(user, auth) сообщения через WebSocket не пойдут — остаются в локальной БД со статусом SENDING / FAILED. Повторный authorize() идемпотентен и поднимает сессию заново.

В приложении:

  • Подпишитесь на networkErrorReceived и покажите офлайн-индикатор.
  • При восстановлении интернета (ConnectivityManager.NetworkCallback) вызовите chatCenterUI.authorize(user, auth) повторно.
  • Keepalive-пинги: интервал задаётся параметром WSConfig.pingInterval (по умолчанию 30 сек) — это только обнаружение разрыва, не запуск переподключения.
  • При превышении connectionTimeout SDK сигнализирует об ошибке через ChatCenterUIListener.networkErrorReceived().

Локальное хранение

  • История сообщений хранится в локальной SQLite-базе SDK. Содержимое БД не шифруется — не передавайте через чат данные, которые ваша политика безопасности запрещает хранить в открытом виде на устройстве.
  • Токены и настройки пользователя хранятся в EncryptedSharedPreferences и переживают перезапуск приложения.
keepWebSocketActive — клиентский fallback

ChatConfig.keepWebSocketActive применяется только если сервер не прислал значение keepSocketActive в channelSettings. Серверная настройка переопределяет клиентскую без обновления приложения. См. Известные ограничения.