Обработка ошибок ================ Если сообщение пришло не целиком, ``decode()`` не сможет его прочитать: .. testcode:: from bytespec import DecodeError, ProtoModel class Message(ProtoModel): text: str encoded = Message(text="Hello").encode() try: Message.decode(encoded[:-1]) except DecodeError: print("Сообщение обрезано или не соответствует модели") .. testoutput:: Сообщение обрезано или не соответствует модели Перехватывайте ``DecodeError`` там, где приложение принимает и читает внешние сообщения. Эта ошибка также обозначает некорректный текст, неизвестное значение enum или другие данные, не подходящие модели. Значение не помещается в поле ----------------------------- .. testcode:: from bytespec import EncodeError from bytespec.types import UInt8 class Packet(ProtoModel): number: UInt8 packet = Packet(number=256) try: packet.encode() except EncodeError as error: print(error) .. testoutput:: Packet.number: UInt8Codec (B): cannot encode 256 ``UInt8`` допускает только числа до 255. Экземпляр создался, но запись завершилась ошибкой. Аналогично обрабатываются слишком длинная строка для выбранного префикса и текст, который нельзя представить в кодировке. Аннотации модели задают формат, но не выполняют полную проверку явно переданных аргументов конструктора. Передавайте значения подходящих типов; не рассчитывайте на преобразование ``"42"`` в число или словаря в модель. Ошибка в объявлении модели -------------------------- Некорректные настройки выявляются уже при создании класса: .. testcode:: from bytespec import SchemaError try: class User(ProtoModel): email: str | None # optional-полю нужен field(flag=...) except SchemaError: print("Добавьте номер flag для email") .. testoutput:: Добавьте номер flag для email ``SchemaError`` также возникает при неподдерживаемой аннотации, повторяющемся индексе или неправильном префиксе длины. Что перехватывать ----------------- .. list-table:: :header-rows: 1 :widths: 27 73 * - Исключение - Значение * - ``SchemaError`` - Невозможно использовать объявленные типы или настройки * - ``EncodeError`` - Значение нельзя записать в выбранном представлении * - ``DecodeError`` - Сообщение нельзя прочитать по этой модели * - ``BytespecError`` - Общий базовый класс трёх ошибок выше Все четыре класса импортируются из ``bytespec``. Если все библиотечные ошибки обрабатываются одинаково, можно перехватывать ``BytespecError``. Полная иерархия и случаи возникновения — :doc:`api/errors`. Ошибки вызова Python остаются обычными исключениями. Например, ``Message()`` без обязательного ``text`` вызывает ``TypeError``. Ошибки реализации собственного codec также не оборачиваются автоматически. Исключения из ``__validate__`` тоже передаются как есть, включая вызов через ``decode()``; обработайте выбранный приложением тип отдельно (см. :doc:`validation`). Проверки header и их текущие ограничения: :ref:`header-validation`. В сообщении ошибки поля есть имя модели и поля; у обёрнутых ошибок исходная причина доступна через ``error.__cause__``. Для диагностики можно вывести исключение целиком, как во втором примере. Не используйте его текст как машинный протокол: отдельные атрибуты ``field`` и ``offset`` не предоставляются. Базовое руководство закончено. Дальше — :doc:`models`, если нужно работать с файлами или несколькими сообщениями; :doc:`codecs`, если нужен свой тип; :doc:`wire-format`, если вы согласовываете бинарный формат с другой стороной.