Skip to content

Exceptions

PDC Struct defines specific exception types for serialization errors. These exceptions provide clear feedback when packing or unpacking operations fail.

Overview

Exception Raised During Common Causes
StructPackError to_bytes() Value out of range, type mismatch, buffer overflow
StructUnpackError from_bytes() Truncated data, invalid header, version mismatch

Both exceptions inherit from Python's built-in Exception class.

StructPackError

Raised when converting a model instance to bytes fails.

Common Causes

Value Out of Range

from pdc_struct import StructModel, StructConfig, StructMode
from pdc_struct.c_types import UInt8

class Packet(StructModel):
    value: UInt8
    struct_config = StructConfig(mode=StructMode.C_COMPATIBLE)

# This will raise StructPackError (via Pydantic validation)
packet = Packet(value=256)  # UInt8 max is 255

String Too Long

from pydantic import Field

class Message(StructModel):
    text: str = Field(json_schema_extra={"max_length": 10})
    struct_config = StructConfig(mode=StructMode.C_COMPATIBLE)

msg = Message(text="This string is way too long")
msg.to_bytes()  # StructPackError: string exceeds max_length

Type Mismatch

class Data(StructModel):
    count: int
    struct_config = StructConfig(mode=StructMode.C_COMPATIBLE)

# Pydantic handles type coercion, but incompatible types fail
data = Data(count="not a number")  # ValidationError from Pydantic

Handling StructPackError

from pdc_struct import StructPackError

try:
    binary_data = my_model.to_bytes()
except StructPackError as e:
    print(f"Failed to serialize: {e}")
    # Handle error - log, return error response, etc.

StructUnpackError

Raised when creating a model instance from bytes fails.

Common Causes

Truncated Data

from pdc_struct import StructUnpackError

class Packet(StructModel):
    x: float  # 8 bytes
    y: float  # 8 bytes
    struct_config = StructConfig(mode=StructMode.C_COMPATIBLE)

# Only 10 bytes provided, but struct needs 16
try:
    packet = Packet.from_bytes(b'\x00' * 10)
except StructUnpackError as e:
    print(f"Data too short: {e}")

Invalid Header (DYNAMIC Mode)

class DynamicPacket(StructModel):
    value: int
    struct_config = StructConfig(mode=StructMode.DYNAMIC)

# Corrupted or invalid header bytes
try:
    packet = DynamicPacket.from_bytes(b'\xff\xff\xff\xff')
except StructUnpackError as e:
    print(f"Invalid header: {e}")

Version Mismatch

# Data was serialized with a different version than expected
try:
    packet = DynamicPacket.from_bytes(data_from_future_version)
except StructUnpackError as e:
    print(f"Version mismatch: {e}")

Handling StructUnpackError

from pdc_struct import StructUnpackError

def parse_packet(data: bytes) -> Optional[Packet]:
    try:
        return Packet.from_bytes(data)
    except StructUnpackError as e:
        logger.error(f"Failed to parse packet: {e}")
        return None

Best Practices

Validate Before Packing

Use Pydantic's validation to catch issues early:

from pydantic import ValidationError

try:
    packet = Packet(value=invalid_value)
except ValidationError as e:
    # Handle validation error before attempting to_bytes()
    print(e.errors())

Defensive Unpacking

Always handle potential errors when deserializing untrusted data:

from pdc_struct import StructUnpackError

def handle_network_data(data: bytes):
    if len(data) < Packet.struct_size():
        raise ValueError("Packet too small")

    try:
        packet = Packet.from_bytes(data)
    except StructUnpackError:
        raise ValueError("Malformed packet")

    return packet

Logging and Debugging

Include context when catching exceptions:

import logging

logger = logging.getLogger(__name__)

try:
    packet = Packet.from_bytes(data)
except StructUnpackError as e:
    logger.error(
        "Failed to unpack packet",
        extra={
            "error": str(e),
            "data_length": len(data),
            "data_hex": data[:32].hex(),  # First 32 bytes
        }
    )
    raise

Exception Reference

StructPackError

Bases: Exception

Raised when there is an error packing data into bytes

Source code in pdc_struct/exc.py
5
6
7
8
class StructPackError(Exception):
    """Raised when there is an error packing data into bytes"""

    pass

StructUnpackError

Bases: Exception

Raised when there is an error unpacking bytes into a model

Source code in pdc_struct/exc.py
class StructUnpackError(Exception):
    """Raised when there is an error unpacking bytes into a model"""

    pass

See Also