Обработка ошибок

Если сообщение пришло не целиком, decode() не сможет его прочитать:

from bytespec import DecodeError, ProtoModel

class Message(ProtoModel):
    text: str

encoded = Message(text="Hello").encode()
try:
    Message.decode(encoded[:-1])
except DecodeError:
    print("Сообщение обрезано или не соответствует модели")
Сообщение обрезано или не соответствует модели

Перехватывайте DecodeError там, где приложение принимает и читает внешние сообщения. Эта ошибка также обозначает некорректный текст, неизвестное значение enum или другие данные, не подходящие модели.

Значение не помещается в поле

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)
Packet.number: UInt8Codec (B): cannot encode 256

UInt8 допускает только числа до 255. Экземпляр создался, но запись завершилась ошибкой. Аналогично обрабатываются слишком длинная строка для выбранного префикса и текст, который нельзя представить в кодировке.

Аннотации модели задают формат, но не выполняют полную проверку явно переданных аргументов конструктора. Передавайте значения подходящих типов; не рассчитывайте на преобразование "42" в число или словаря в модель.

Ошибка в объявлении модели

Некорректные настройки выявляются уже при создании класса:

from bytespec import SchemaError

try:
    class User(ProtoModel):
        email: str | None  # optional-полю нужен field(flag=...)
except SchemaError:
    print("Добавьте номер flag для email")
Добавьте номер flag для email

SchemaError также возникает при неподдерживаемой аннотации, повторяющемся индексе или неправильном префиксе длины.

Что перехватывать

Исключение

Значение

SchemaError

Невозможно использовать объявленные типы или настройки

EncodeError

Значение нельзя записать в выбранном представлении

DecodeError

Сообщение нельзя прочитать по этой модели

BytespecError

Общий базовый класс трёх ошибок выше

Все четыре класса импортируются из bytespec. Если все библиотечные ошибки обрабатываются одинаково, можно перехватывать BytespecError. Полная иерархия и случаи возникновения — Исключения.

Ошибки вызова Python остаются обычными исключениями. Например, Message() без обязательного text вызывает TypeError. Ошибки реализации собственного codec также не оборачиваются автоматически. Исключения из __validate__ тоже передаются как есть, включая вызов через decode(); обработайте выбранный приложением тип отдельно (см. Проверка значений модели). Проверки header и их текущие ограничения: Что проверяется в 0.1.0.

В сообщении ошибки поля есть имя модели и поля; у обёрнутых ошибок исходная причина доступна через error.__cause__. Для диагностики можно вывести исключение целиком, как во втором примере. Не используйте его текст как машинный протокол: отдельные атрибуты field и offset не предоставляются.

Базовое руководство закончено. Дальше — Файлы и несколько сообщений, если нужно работать с файлами или несколькими сообщениями; Codecs: свой формат и свои типы, если нужен свой тип; Binary / wire format, если вы согласовываете бинарный формат с другой стороной.