Exceptions

All exceptions raised by the library. Located in pepper_c1/exceptions.py. All are importable directly from pepper_c1.

TransportError transport
Raised when a physical connection or I/O error occurs — port cannot be opened, connection refused, socket closed unexpectedly, or read/write failure.

Base class: Exception

When raised:

  • Serial port not available or permission denied (UARTTransport)
  • TCP connection refused or timed out (TCPTransport)
  • Read/write error on an already-open connection
  • Timeout in Transport.read_frame()
from pepper_c1 import PepperC1, UARTTransport, TransportError

try:
    with PepperC1(UARTTransport('COM99')) as reader:
        reader.get_version()
except TransportError as e:
    print(f"Cannot connect: {e}")
CommandError command
Raised when the reader responds with a CMD_ERROR frame (first byte 0xFF), meaning the device rejected or failed to execute the command. Contains the failing command opcode and a device-specific error code.

Base class: Exception

AttributeTypeDescription
cmdintCommand opcode that failed (e.g. 0x20 for MF_READ_BLOCK).
error_codeintDevice-specific 16-bit error code returned by the reader.

When raised:

  • Authentication failure (wrong key)
  • Block/page out of range
  • Command not supported by the tag type
  • Tag removed from field mid-operation
  • Access denied by tag configuration
from pepper_c1 import CommandError

try:
    reader.mf_read_block(5)
except CommandError as e:
    print(f"Command 0x{e.cmd:02X} failed, error code: 0x{e.error_code:04X}")
    # e.g. "Command 0x20 failed, error code: 0x0004"
ProtocolError protocol
Raised when a received frame fails validation — wrong start byte, length XOR mismatch, CRC failure, or unexpected frame length. Indicates a communication integrity problem, not an application error.

Base class: Exception

When raised:

  • Received data does not start with 0xF5 (STX)
  • Frame length XOR check fails
  • CCITT-16 CRC mismatch between computed and received value
  • Response payload length doesn't match expected (e.g. in mf_read_block)
from pepper_c1 import ProtocolError

try:
    data = reader.mf_read_block(5)
except ProtocolError as e:
    print(f"Protocol integrity error: {e}")

TimeoutError

TimeoutError is a built-in Python exception (not defined by this library) raised by send_command() when no valid response arrives within response_timeout seconds. Catch it as except TimeoutError.

Complete Error Handling Example

import sys
from pepper_c1 import (
    PepperC1, UARTTransport,
    CommandError, TransportError, ProtocolError,
)

try:
    with PepperC1(UARTTransport('COM3')) as reader:
        count = reader.get_tag_count()
        if count == 0:
            print("No tag")
            sys.exit(0)
        reader.activate_tag(0)
        data = reader.mf_read_block(5)
        print(data.hex())

except TransportError as e:
    print(f"Connection error: {e}", file=sys.stderr)
    sys.exit(1)

except CommandError as e:
    print(f"Device error on cmd 0x{e.cmd:02X}: 0x{e.error_code:04X}", file=sys.stderr)
    sys.exit(2)

except ProtocolError as e:
    print(f"Protocol integrity failure: {e}", file=sys.stderr)
    sys.exit(3)

except TimeoutError:
    print("Reader did not respond in time", file=sys.stderr)
    sys.exit(4)