Skip to content

v0.9.0 - Graceful Error Handling and Streaming Statistics (2025-12-27)

What Changed?

This release improves robustness and visibility during event collection. Malformed JSON responses from the detector are now handled gracefully—skipped with warnings instead of crashing data collection. Additionally, new streaming statistics tracking provides detailed insight into successful events, timeouts, and parsing errors, making it easy to understand data quality during measurement sessions.


What's New

Feature 1: Streaming Statistics Tracking

What it does: The Streamer base class (used by both Reader and Measure) now tracks comprehensive event streaming statistics. Each streaming operation automatically counts successful events, timeouts, and parsing errors (separated by error type). Access statistics via the .stats property which returns a StreamingStats dataclass with fields for total events yielded, skipped timeouts, protocol errors, and response errors—plus computed properties for success rate and total attempts.

How to use it: No changes needed for existing code! Statistics are collected automatically. Access them after streaming:

from kazunoko import Reader, connect

with connect(port="auto") as device:
    reader = Reader(device)
    for event in reader.stream_by_count(1000):
        print(event.model_dump_json())

    # Get statistics
    stats = reader.stats
    print(f"Events received: {stats.total_yielded}")
    print(f"Events skipped: {stats.total_skipped}")
    print(f"Success rate: {stats.success_rate:.1f}%")
    print(f"  - Timeouts: {stats.skipped_timeout}")
    print(f"  - Protocol errors: {stats.skipped_protocol}")
    print(f"  - Response errors: {stats.skipped_response}")

CLI integration: The read and measure commands automatically log and display statistics when --verbose is used:

# Show statistics breakdown if events were skipped
uv run kazunoko read 1000 --verbose

# Output includes:
# ✓ Total events received: 998
# ⚠ Skipped events: 2 (99.8% success)
#   - Timeout: 0
#   - Protocol errors: 1
#   - Response errors: 1

Feature 2: Graceful Malformed Response Handling (from v0.8.0)

What it does: When the detector sends corrupted or incomplete JSON responses, kazunoko now gracefully skips the bad packet with a warning and continues collecting events. Previously, a single malformed response would crash the entire data collection process. This feature was introduced in v0.8.0 and is fully integrated in v0.9.0 with statistics tracking.

How to use it: No code changes needed—it works automatically! When a malformed packet is received during stream_by_count() or stream_by_time():

  1. A warning is logged with error details
  2. A yellow warning message appears on stderr
  3. The bad packet is skipped (not yielded)
  4. Collection continues to the next event
  5. The skip is counted in stats.skipped_protocol or stats.skipped_response

Installation

Quick Start

# Get the release
git checkout v0.9.0

# Setup
uv sync

# Run CLI
uv run kazunoko --help

What's Different from the Last Version?

✅ Added

  • StreamingStats dataclass for tracking event streaming statistics (total_yielded, skipped_timeout, skipped_protocol, skipped_response)
  • stats property on Streamer base class to access current streaming statistics
  • reset_stats() method on Streamer to reset statistics to zero
  • Automatic statistics collection in stream_by_count() and stream_by_time() methods
  • Detailed statistics display in CLI read and measure commands with --verbose flag
  • StreamingStats exported in public API (__init__.py)
  • Graceful error handling for malformed JSON responses (from v0.8.0)
  • Separate tracking for ProtocolError and ResponseError (distinct skip counters)

🔧 Changed

  • stream_by_count() now tracks successful yields and skipped events by type
  • stream_by_time() now tracks successful yields and skipped events by type
  • CLI read command uses reader.stats instead of manual event counter
  • CLI measure command uses measure.stats instead of manual event counter
  • Exception handling in streaming methods split ProtocolError and ResponseError into separate handlers

🐛 Fixed

  • Data collection no longer stops when detector sends corrupted JSON (handles gracefully with statistics tracking)
  • Malformed packets are now counted separately from timeout errors for better diagnostics
  • Temporary communication glitches no longer result in total data loss

Is It Safe to Upgrade?

Backward Compatible: Yes

  • No API changes; all existing code works unchanged
  • Statistics collection is automatic but optional to use
  • Error handling is more lenient (catches errors that previously caused crashes)
  • CLI commands show additional statistics information only with --verbose flag
  • All examples and existing CLI commands continue to work as before
  • Library behavior is transparent; users who don't use .stats won't notice any changes

Tests Passed

  • ✅ Builds without errors
  • ✅ Linting passes (ruff check)
  • ✅ Type checking compatible with mypy
  • ✅ Statistics tracking verified (StreamingStats dataclass functionality)
  • ✅ Exception handling tested (ProtocolError, ResponseError, EventTimeout caught correctly)
  • ✅ CLI integration verified (read and measure commands with statistics output)

Release Details

  • Date: 2025-12-27
  • Version: v0.9.0
  • Files Changed: 3 (measure.py, cli.py, __init__.py)
  • Commits:
  • d4316bf (feat: add streaming statistics tracking for skipped events)
  • 82c53a6 (bump: version 0.8.0 → 0.9.0)
  • Earlier: 96b7535 (feat: add graceful error handling for malformed JSON responses)

Next Steps

  • Monitor field testing for additional edge cases with malformed responses
  • Consider adding retry logic for transient communication failures
  • Potential enhancement: automatically collect statistics in CLI output without --verbose flag
  • Continued improvements to error recovery and robustness during long-running data collection sessions