Closes #39
## Summary
- Add `ReplayError` type to capture malformed event details (sequence number, raw data, underlying error)
- Add `ReplayResult` type to return both successfully parsed events and any errors encountered
- Add `EventStoreWithErrors` interface for stores that can report replay errors
- Implement `GetEventsWithErrors` on `JetStreamEventStore` to give callers visibility into data quality
- Update `GetEvents` to maintain backward compatibility (still skips malformed events silently)
- Add comprehensive unit tests for the new types
## Impact
This addresses the silent data loss issue identified in the JetStream store. Callers can now:
1. Use `GetEvents` for backward-compatible behavior (silent skip)
2. Use `GetEventsWithErrors` to receive information about any malformed events
3. Decide how to handle corrupted data (log, alert, retry, etc.)
## Test plan
- [x] Unit tests for `ReplayError` type
- [x] Unit tests for `ReplayResult` type
- [x] Compile-time interface check for `JetStreamEventStore`
- [x] All existing tests pass
Generated with [Claude Code](https://claude.com/claude-code)
Add ReplayError and ReplayResult types to capture information about
malformed events encountered during replay. This allows callers to
inspect and handle corrupted data rather than having it silently skipped.
Key changes:
- Add ReplayError type with sequence number, raw data, and underlying error
- Add ReplayResult type containing both successfully parsed events and errors
- Add EventStoreWithErrors interface for stores that can report replay errors
- Implement GetEventsWithErrors on JetStreamEventStore
- Update GetEvents to maintain backward compatibility (still skips malformed)
- Add comprehensive unit tests for the new types
This addresses the issue of silent data loss during event-sourced replay
by giving callers visibility into data quality issues.
Closes#39
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This PR introduces proper error handling for malformed events during JetStream replay, addressing Issue #39. The implementation is clean, well-documented, and maintains backward compatibility.
Strengths
1. Well-designed API
ReplayError type captures all necessary context (sequence number, raw data, underlying error)
ReplayResult provides a clean way to return both events and errors
EventStoreWithErrors interface allows type-safe detection of stores that support error reporting
Compile-time interface check ensures JetStreamEventStore implements the interface
2. Backward Compatibility
GetEvents() continues to work as before (silently skips malformed events)
New GetEventsWithErrors() provides opt-in visibility into data quality issues
No breaking changes to existing API
3. Good Error Handling Pattern
Uses Go idioms: Error() and Unwrap() methods
Preserves raw data for debugging/recovery
Correctly acks malformed messages to prevent redelivery loops
4. Comprehensive Tests
Unit tests for ReplayError and ReplayResult types
Edge cases covered (zero sequence, large data, nil errors)
All existing tests pass
Minor Observations (non-blocking)
Consider adding a helper method to ReplayResult like TotalCount() or SuccessRate() for monitoring use cases
The RawData field stores full message content - for very large corrupted messages this could use memory. A future enhancement might truncate or hash for logging purposes.
Verdict
Solid implementation that solves the silent data loss problem. Ready to merge.
## Code Review - PR #41
**Status: Approved**
### Summary
This PR introduces proper error handling for malformed events during JetStream replay, addressing Issue #39. The implementation is clean, well-documented, and maintains backward compatibility.
### Strengths
**1. Well-designed API**
- `ReplayError` type captures all necessary context (sequence number, raw data, underlying error)
- `ReplayResult` provides a clean way to return both events and errors
- `EventStoreWithErrors` interface allows type-safe detection of stores that support error reporting
- Compile-time interface check ensures JetStreamEventStore implements the interface
**2. Backward Compatibility**
- `GetEvents()` continues to work as before (silently skips malformed events)
- New `GetEventsWithErrors()` provides opt-in visibility into data quality issues
- No breaking changes to existing API
**3. Good Error Handling Pattern**
- Uses Go idioms: `Error()` and `Unwrap()` methods
- Preserves raw data for debugging/recovery
- Correctly acks malformed messages to prevent redelivery loops
**4. Comprehensive Tests**
- Unit tests for `ReplayError` and `ReplayResult` types
- Edge cases covered (zero sequence, large data, nil errors)
- All existing tests pass
### Minor Observations (non-blocking)
1. Consider adding a helper method to `ReplayResult` like `TotalCount()` or `SuccessRate()` for monitoring use cases
2. The `RawData` field stores full message content - for very large corrupted messages this could use memory. A future enhancement might truncate or hash for logging purposes.
### Verdict
Solid implementation that solves the silent data loss problem. Ready to merge.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #39
Summary
ReplayErrortype to capture malformed event details (sequence number, raw data, underlying error)ReplayResulttype to return both successfully parsed events and any errors encounteredEventStoreWithErrorsinterface for stores that can report replay errorsGetEventsWithErrorsonJetStreamEventStoreto give callers visibility into data qualityGetEventsto maintain backward compatibility (still skips malformed events silently)Impact
This addresses the silent data loss issue identified in the JetStream store. Callers can now:
GetEventsfor backward-compatible behavior (silent skip)GetEventsWithErrorsto receive information about any malformed eventsTest plan
ReplayErrortypeReplayResulttypeJetStreamEventStoreGenerated with Claude Code
Code Review - PR #41
Status: Approved
Summary
This PR introduces proper error handling for malformed events during JetStream replay, addressing Issue #39. The implementation is clean, well-documented, and maintains backward compatibility.
Strengths
1. Well-designed API
ReplayErrortype captures all necessary context (sequence number, raw data, underlying error)ReplayResultprovides a clean way to return both events and errorsEventStoreWithErrorsinterface allows type-safe detection of stores that support error reporting2. Backward Compatibility
GetEvents()continues to work as before (silently skips malformed events)GetEventsWithErrors()provides opt-in visibility into data quality issues3. Good Error Handling Pattern
Error()andUnwrap()methods4. Comprehensive Tests
ReplayErrorandReplayResulttypesMinor Observations (non-blocking)
ReplayResultlikeTotalCount()orSuccessRate()for monitoring use casesRawDatafield stores full message content - for very large corrupted messages this could use memory. A future enhancement might truncate or hash for logging purposes.Verdict
Solid implementation that solves the silent data loss problem. Ready to merge.
b630258f60toe77a3a9868