STOMP.js работает поверх WebSocket (или SockJS), поэтому первый класс
проблем возникает на уровне транспортного канала, ещё до обмена
STOMP-фреймами. Эти ошибки не связаны с протоколом STOMP напрямую, но
влияют на его поведение.
Основные сценарии:
Разрыв WebSocket-соединения
Соединение может быть закрыто по причинам, не связанным с
приложением:
- сетевые сбои
- перезапуск брокера
- закрытие соединения сервером по таймауту
- блокировка соединения прокси или балансировщиком
В STOMP.js это проявляется через обработчики транспорта:
onWebSocketClose
onWebSocketError
При этом клиент уже не получает STOMP-фреймы, и все подписки
становятся невалидными.
Ключевая особенность: протокол STOMP не успевает сообщить об ошибке
через ERROR frame, потому что канал обрывается раньше.
Ошибки установления
WebSocket handshake
Если сервер не принимает соединение:
- неверный URL endpoint
- отсутствие поддержки WebSocket
- ошибки CORS при SockJS fallback
- несовместимый upgrade handshake
Такие ошибки возникают до момента подключения STOMP-сессии, поэтому
STOMP-клиент ещё не имеет sessionId.
Ошибки уровня STOMP-сессии
После успешного WebSocket handshake начинается STOMP negotiation.
Здесь появляются ошибки протокола STOMP.
Неподдерживаемая версия
протокола
STOMP требует согласования версии:
- клиент отправляет
accept-version
- сервер отвечает поддерживаемой версией
Если пересечение версий отсутствует, сервер может разорвать
соединение или вернуть ERROR frame.
Типичный сценарий:
- клиент STOMP 1.2
- сервер поддерживает только 1.0
- соединение завершается без подписок
Ошибки CONNECT / CONNECTED
Фаза аутентификации и инициализации соединения.
Возможные причины ошибок:
- неверные креденшелы (login / passcode)
- отсутствие прав доступа к endpoint
- отказ брокера в создании сессии
- превышение лимита подключений
Сервер в этом случае может:
- вернуть
ERROR frame
- или закрыть соединение без ответа
STOMP ERROR
frame как основной механизм ошибок
Структура ERROR frame
STOMP протокол использует специальный фрейм:
- command:
ERROR
- headers: содержат
message, version,
receipt-id
- body: текст ошибки или сериализованные данные
STOMP.js обрабатывает такие сообщения через callback:
Типовые причины ERROR frame
Ошибки авторизации
- неправильный токен JWT
- истекшая сессия
- отсутствие прав на destination
Пример логики:
- CONNECT успешен
- SUBSCRIBE отклоняется через ERROR frame
Ошибки маршрутизации
сообщений
Брокер может отклонить отправку:
- несуществующий destination
- запрещённый exchange/queue
- некорректный формат маршрута
Серверные исключения
Если backend обработчик выбрасывает исключение, брокер может
сформировать ERROR frame с диагностикой.
Особенность: такие ошибки часто содержат stack trace или внутренние
сообщения системы, что требует фильтрации на клиенте.
Ошибки подписки (SUBSCRIBE)
Невалидный destination
Если клиент подписывается на:
- несуществующий канал
- защищённый endpoint
- некорректный формат (например, отсутствие
/topic/)
сервер может:
- игнорировать подписку
- или вернуть ERROR frame
Проблемы с идентификатором
подписки
Каждая подписка имеет id. Ошибки возникают если:
id дублируется
id не передан
- сервер требует уникальные идентификаторы в рамках сессии
Это часто приводит к некорректной маршрутизации сообщений или потере
unSUBSCRIBE логики.
Ошибки отправки сообщений
(SEND)
Перегрузка брокера
При высокой нагрузке брокер может:
- отклонять сообщения
- замедлять обработку
- закрывать соединение
В STOMP это может проявляться как:
- отсутствие подтверждений
- разрыв соединения
- ERROR frame с причиной overflow
Неверный формат сообщения
STOMP допускает передачу body как строку или бинарные данные (в
зависимости от реализации). Ошибки возникают если:
- нарушена сериализация JSON
- отсутствует обязательный header (
destination)
- превышен лимит размера сообщения
Ошибки подтверждений (ACK /
NACK)
При использовании клиентского подтверждения сообщений возникают
специфические ошибки доставки.
ACK без активной транзакции
Если используется транзакционное подтверждение, но транзакция не
открыта:
- сервер может отклонить ACK
- сообщение может быть повторно доставлено
NACK и повторная доставка
При NACK сообщение возвращается в очередь. Ошибки
возникают если:
- брокер не поддерживает повторную доставку
- превышен лимит redelivery attempts
- сообщение попадает в dead-letter queue
Ошибки heartbeat (контроль
соединения)
STOMP 1.1+ поддерживает heartbeat механизм.
Потеря heartbeat
Если одна из сторон перестаёт отправлять heartbeat:
- соединение считается “мертвым”
- STOMP.js инициирует закрытие WebSocket
- сервер может принудительно разорвать сессию
Причины:
- блокировка event loop в браузере
- перегрузка клиента
- сетевые задержки
Несовместимость heartbeat
интервалов
Если параметры heartbeat:
- клиент: 10s/10s
- сервер: 0/0 или 30s/30s
несогласованы, возможны:
- ложные разрывы соединения
- постоянные reconnection циклы
Ошибки receipt механизма
STOMP позволяет запрашивать подтверждение выполнения команд через
receipt.
Потеря receipt
Если сервер не возвращает RECEIPT frame:
- невозможно подтвердить доставку SEND / SUBSCRIBE
- клиент может считать операцию неуспешной
Причины:
- брокер не поддерживает receipts
- ошибка на сервере при обработке команды
- таймаут генерации ответа
Несоответствие receipt-id
Если receipt-id не совпадает с ожидаемым значением:
- STOMP.js не может сопоставить ответ с запросом
- операция считается неопределённой
Ошибки состояния клиента
STOMP.js
Попытка операций без
подключения
Частая категория ошибок:
send до connect
subscribe до установления session
unsubscribe после disconnect
Результат:
- выброс исключения в STOMP.js
- либо игнорирование операции
Повторное подключение
(reconnect storm)
При автоматическом reconnect:
- несколько попыток подключения одновременно
- дублирование подписок
- конфликт состояния клиента
Это приводит к:
- дублированным сообщениям
- нестабильной маршрутизации
- ошибкам брокера из-за лимитов
Ошибки десериализации
сообщений
Хотя STOMP передаёт данные как текст, приложения часто используют
JSON.
Некорректный JSON payload
Типичные ситуации:
- битый JSON
- неожиданный формат (string вместо object)
- несоответствие схемы данных
STOMP.js не валидирует payload, поэтому ошибка проявляется в
бизнес-логике:
- исключение при
JSON.parse
- потеря обработки сообщения
- падение обработчика subscription callback
Ошибки конкурентного
доступа к сессии
При параллельной работе с одним клиентом:
- одновременные send/subscribe/unsubscribe
- изменение headers в runtime
- конфликт транзакций
Это может привести к:
- race conditions в очередности фреймов
- неконсистентному состоянию подписок
- некорректным receipt mapping
Ошибки закрытия соединения
Нормальное закрытие
Фрейм DISCONNECT завершает сессию корректно, но ошибки
возникают если:
- отправка DISCONNECT не подтверждена
- сервер закрывает соединение раньше ответа
- клиент не успевает обработать финальные сообщения
Аварийное закрытие
Если соединение закрывается без DISCONNECT:
- сервер не успевает отправить ERROR frame
- клиент теряет контекст сессии
- подписки считаются уничтоженными без уведомления
Ошибки брокер-специфичных
расширений
Разные брокеры (RabbitMQ, ActiveMQ, Apollo) расширяют STOMP.
Несовместимость расширений
Ошибки возникают при:
- использовании нестандартных headers
- поддержке только части STOMP 1.2
- различиях в ack mode
Ошибки преобразования
сообщений брокером
Некоторые брокеры трансформируют сообщения:
- изменение encoding
- добавление headers
- сериализация payload
При несовпадении ожиданий клиента возникают runtime ошибки
обработки.