Conversation
…l crates - Add context fields (stream_id, expected, actual) to EventStoreError::VersionConflict across all backends (memory, sqlite, postgres) and update all pattern matches throughout the workspace - Remove production panics: replace .expect() in SQLite's try_acquire_lock (now returns LockPoisoned error) and append_events version counter lookup (now returns UndeclaredStream) - Fix cross-backend coordination error inconsistency: all three backends now include subscription_name in LeadershipNotAcquired error messages - Convert manual Display impls to thiserror derives: InMemoryCheckpointError, InMemoryCoordinationError, NoCheckpointError, ContractTestFailure - Differentiate duplicate macro error messages: non-struct vs tuple struct errors now have distinct messages in #[derive(Command)] - Fix example anti-pattern: Withdraw::handle in single_stream_command_test now uses typed WithdrawError enum instead of direct CommandError::BusinessRuleViolation construction
jwilger
requested changes
Apr 12, 2026
Change BusinessRuleViolation(String) to BusinessRuleViolation(Box<dyn Error>) to preserve the Rust error chain convention. From impls now use Box::new(e) instead of e.to_string(). Added BusinessRuleMessage helper type for string-based errors from the require! macro.
jwilger
approved these changes
Apr 12, 2026
Merged
jwilger
added a commit
that referenced
this pull request
Apr 13, 2026
## 🤖 New release
* `eventcore-macros`: 0.6.0 -> 0.7.0
* `eventcore-types`: 0.6.0 -> 0.7.0 (⚠ API breaking changes)
* `eventcore-postgres`: 0.6.0 -> 0.7.0 (⚠ API breaking changes)
* `eventcore-sqlite`: 0.6.0 -> 0.7.0 (⚠ API breaking changes)
* `eventcore`: 0.6.0 -> 0.7.0 (⚠ API breaking changes)
* `eventcore-memory`: 0.6.0 -> 0.7.0 (⚠ API breaking changes)
* `eventcore-testing`: 0.6.0 -> 0.7.0 (✓ API compatible changes)
* `eventcore-examples`: 0.6.0 -> 0.7.0 (✓ API compatible changes)
### ⚠ `eventcore-types` breaking changes
```text
--- failure auto_trait_impl_removed: auto trait no longer implemented ---
Description:
A public type has stopped implementing one or more auto traits. This can break downstream code that depends on the traits being implemented.
ref: https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/auto_trait_impl_removed.ron
Failed in:
type CommandError is no longer UnwindSafe, in /tmp/.tmp9Ta52e/eventcore/eventcore-types/src/errors.rs:21
type CommandError is no longer RefUnwindSafe, in /tmp/.tmp9Ta52e/eventcore/eventcore-types/src/errors.rs:21
--- failure enum_unit_variant_changed_kind: An enum unit variant changed kind ---
Description:
A public enum's exhaustive unit variant has changed to a different kind of enum variant, breaking possible instantiations and patterns.
ref: https://doc.rust-lang.org/reference/items/enumerations.html
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/enum_unit_variant_changed_kind.ron
Failed in:
variant EventStoreError::VersionConflict in /tmp/.tmp9Ta52e/eventcore/eventcore-types/src/store.rs:381
--- failure trait_added_supertrait: non-sealed trait added new supertraits ---
Description:
A non-sealed trait added one or more supertraits, which breaks downstream implementations of the trait
ref: https://doc.rust-lang.org/cargo/reference/semver.html#generic-bounds-tighten
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/trait_added_supertrait.ron
Failed in:
trait eventcore_types::CommandLogic gained Send in file /tmp/.tmp9Ta52e/eventcore/eventcore-types/src/command.rs:149
trait eventcore_types::CommandLogic gained Sync in file /tmp/.tmp9Ta52e/eventcore/eventcore-types/src/command.rs:149
--- failure trait_method_added: pub trait method added ---
Description:
A non-sealed public trait added a new method without a default implementation, which breaks downstream implementations of the trait
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-item-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/trait_method_added.ron
Failed in:
trait method eventcore_types::Event::event_type_name in file /tmp/.tmp9Ta52e/eventcore/eventcore-types/src/command.rs:128
```
### ⚠ `eventcore-postgres` breaking changes
```text
--- failure enum_unit_variant_changed_kind: An enum unit variant changed kind ---
Description:
A public enum's exhaustive unit variant has changed to a different kind of enum variant, breaking possible instantiations and patterns.
ref: https://doc.rust-lang.org/reference/items/enumerations.html
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/enum_unit_variant_changed_kind.ron
Failed in:
variant CoordinationError::LeadershipNotAcquired in /tmp/.tmp9Ta52e/eventcore/eventcore-postgres/src/lib.rs:540
```
### ⚠ `eventcore-sqlite` breaking changes
```text
--- failure enum_variant_added: enum variant added on exhaustive enum ---
Description:
A publicly-visible enum without #[non_exhaustive] has a new variant.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#enum-variant-new
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/enum_variant_added.ron
Failed in:
variant SqliteCoordinationError:LockPoisoned in /tmp/.tmp9Ta52e/eventcore/eventcore-sqlite/src/lib.rs:57
```
### ⚠ `eventcore` breaking changes
```text
--- failure enum_missing: pub enum removed or renamed ---
Description:
A publicly-visible enum cannot be imported by its prior path. A `pub use` may have been removed, or the enum itself may have been renamed or removed entirely.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/enum_missing.ron
Failed in:
enum eventcore::PollMode, previously in file /tmp/.tmpiyxp8q/eventcore/src/projection.rs:101
--- failure function_parameter_count_changed: pub fn parameter count changed ---
Description:
A publicly-visible function now takes a different number of parameters.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#fn-change-arity
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/function_parameter_count_changed.ron
Failed in:
eventcore::run_projection now takes 3 parameters instead of 2, in /tmp/.tmp9Ta52e/eventcore/eventcore/src/projection.rs:586
--- failure struct_missing: pub struct removed or renamed ---
Description:
A publicly-visible struct cannot be imported by its prior path. A `pub use` may have been removed, or the struct itself may have been renamed or removed entirely.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/struct_missing.ron
Failed in:
struct eventcore::NoCheckpointStore, previously in file /tmp/.tmpiyxp8q/eventcore/src/projection.rs:161
struct eventcore::ProjectionRunner, previously in file /tmp/.tmpiyxp8q/eventcore/src/projection.rs:141
struct eventcore::PollConfig, previously in file /tmp/.tmpiyxp8q/eventcore/src/projection.rs:26
struct eventcore::EventRetryConfig, previously in file /tmp/.tmpiyxp8q/eventcore/src/projection.rs:72
```
### ⚠ `eventcore-memory` breaking changes
```text
--- failure struct_with_no_pub_fields_changed_type: public API struct with no public fields is no longer a struct ---
Description:
A struct without pub fields became an enum or union, breaking pattern matching.
ref: https://internals.rust-lang.org/t/rest-patterns-foo-should-match-non-struct-types/21607
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/struct_with_no_pub_fields_changed_type.ron
Failed in:
struct eventcore_memory::InMemoryCheckpointError became enum in file /tmp/.tmp9Ta52e/eventcore/eventcore-memory/src/lib.rs:324
```
<details><summary><i><b>Changelog</b></i></summary><p>
## `eventcore-macros`
<blockquote>
##
[0.7.0](eventcore-macros-v0.6.0...eventcore-macros-v0.7.0)
- 2026-04-13
### Bug Fixes
- improve error message consistency, context, and safety across all
crates ([#352](#352))
### Features
- enhance require! macro to accept typed error values
([#335](#335))
- add required event_type_name() to Event trait for stable storage
([#344](#344))
### Miscellaneous Tasks
- adopt han plugins, blueprints, and project conventions
([#330](#330))
- consolidate workspace lints and enforce strict lint policy
([#351](#351))
### Refactoring
- expose projection config via free function API, then reduce public
surface ([#357](#357))
</blockquote>
## `eventcore-types`
<blockquote>
##
[0.7.0](eventcore-types-v0.6.0...eventcore-types-v0.7.0)
- 2026-04-13
### Bug Fixes
- add Send+Sync bounds to CommandLogic for Send futures
([#332](#332))
- improve error message consistency, context, and safety across all
crates ([#352](#352))
### Features
- enhance require! macro to accept typed error values
([#335](#335))
- add required event_type_name() to Event trait for stable storage
([#344](#344))
### Miscellaneous Tasks
- consolidate workspace lints and enforce strict lint policy
([#351](#351))
### Refactoring
- replace into_inner() with into() for nutype domain types
([#334](#334))
</blockquote>
## `eventcore-postgres`
<blockquote>
##
[0.7.0](eventcore-postgres-v0.6.0...eventcore-postgres-v0.7.0)
- 2026-04-13
### Bug Fixes
- improve error message consistency, context, and safety across all
crates ([#352](#352))
### Features
- add required event_type_name() to Event trait for stable storage
([#344](#344))
### Miscellaneous Tasks
- adopt han plugins, blueprints, and project conventions
([#330](#330))
- consolidate workspace lints and enforce strict lint policy
([#351](#351))
</blockquote>
## `eventcore-sqlite`
<blockquote>
##
[0.7.0](eventcore-sqlite-v0.6.0...eventcore-sqlite-v0.7.0)
- 2026-04-13
### Bug Fixes
- apply PRAGMA key before WAL mode in SQLite encrypted stores
([#333](#333))
- improve error message consistency, context, and safety across all
crates ([#352](#352))
### Miscellaneous Tasks
- consolidate workspace lints and enforce strict lint policy
([#351](#351))
</blockquote>
## `eventcore`
<blockquote>
##
[0.7.0](eventcore-v0.6.0...eventcore-v0.7.0)
- 2026-04-13
### Bug Fixes
- improve error message consistency, context, and safety across all
crates ([#352](#352))
### Features
- enhance require! macro to accept typed error values
([#335](#335))
- add required event_type_name() to Event trait for stable storage
([#344](#344))
### Miscellaneous Tasks
- adopt han plugins, blueprints, and project conventions
([#330](#330))
- consolidate workspace lints and enforce strict lint policy
([#351](#351))
### Refactoring
- replace into_inner() with into() for nutype domain types
([#334](#334))
- extract pure state machines from execute() and run()
([#349](#349))
- expose projection config via free function API, then reduce public
surface ([#357](#357))
</blockquote>
## `eventcore-memory`
<blockquote>
##
[0.7.0](eventcore-memory-v0.6.0...eventcore-memory-v0.7.0)
- 2026-04-13
### Bug Fixes
- make InMemoryEventStore error on read_stream type mismatch
([#342](#342))
- improve error message consistency, context, and safety across all
crates ([#352](#352))
### Features
- add required event_type_name() to Event trait for stable storage
([#344](#344))
### Miscellaneous Tasks
- consolidate workspace lints and enforce strict lint policy
([#351](#351))
</blockquote>
## `eventcore-testing`
<blockquote>
##
[0.7.0](eventcore-testing-v0.6.0...eventcore-testing-v0.7.0)
- 2026-04-13
### Bug Fixes
- make InMemoryEventStore error on read_stream type mismatch
([#342](#342))
- improve error message consistency, context, and safety across all
crates ([#352](#352))
### Features
- add required event_type_name() to Event trait for stable storage
([#344](#344))
- add TestScenario GWT testing helpers to eventcore-testing
([#346](#346))
### Miscellaneous Tasks
- consolidate workspace lints and enforce strict lint policy
([#351](#351))
### Refactoring
- expose projection config via free function API, then reduce public
surface ([#357](#357))
</blockquote>
## `eventcore-examples`
<blockquote>
##
[0.7.0](eventcore-examples-v0.6.0...eventcore-examples-v0.7.0)
- 2026-04-13
### Bug Fixes
- improve error message consistency, context, and safety across all
crates ([#352](#352))
### Features
- add required event_type_name() to Event trait for stable storage
([#344](#344))
- add TestScenario GWT testing helpers to eventcore-testing
([#346](#346))
### Miscellaneous Tasks
- consolidate workspace lints and enforce strict lint policy
([#351](#351))
### Refactoring
- replace into_inner() with into() for nutype domain types
([#334](#334))
- expose projection config via free function API, then reduce public
surface ([#357](#357))
</blockquote>
</p></details>
---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).
Merged
jwilger-ai-bot
pushed a commit
that referenced
this pull request
Apr 17, 2026
## 🤖 New release * `eventcore-macros`: 0.7.0 -> 0.7.1 * `eventcore-types`: 0.7.0 -> 0.7.1 (✓ API compatible changes) * `eventcore-postgres`: 0.7.0 -> 0.7.1 (✓ API compatible changes) * `eventcore-sqlite`: 0.7.0 -> 0.7.1 (✓ API compatible changes) * `eventcore`: 0.7.0 -> 0.7.1 (✓ API compatible changes) * `eventcore-memory`: 0.7.0 -> 0.7.1 (✓ API compatible changes) * `eventcore-testing`: 0.7.0 -> 0.7.1 (✓ API compatible changes) * `eventcore-examples`: 0.7.0 -> 0.7.1 <details><summary><i><b>Changelog</b></i></summary><p> ## `eventcore-macros` <blockquote> ## [0.7.0](eventcore-macros-v0.6.0...eventcore-macros-v0.7.0) - 2026-04-13 ### Bug Fixes - improve error message consistency, context, and safety across all crates ([#352](#352)) ### Features - enhance require! macro to accept typed error values ([#335](#335)) - add required event_type_name() to Event trait for stable storage ([#344](#344)) ### Miscellaneous Tasks - adopt han plugins, blueprints, and project conventions ([#330](#330)) - consolidate workspace lints and enforce strict lint policy ([#351](#351)) ### Refactoring - expose projection config via free function API, then reduce public surface ([#357](#357)) </blockquote> ## `eventcore-types` <blockquote> ## [0.7.1](eventcore-types-v0.7.0...eventcore-types-v0.7.1) - 2026-04-15 ### Bug Fixes - filter read_events by event_type to prevent projection stalls ([#373](#373)) </blockquote> ## `eventcore-postgres` <blockquote> ## [0.7.1](eventcore-postgres-v0.7.0...eventcore-postgres-v0.7.1) - 2026-04-15 ### Bug Fixes - filter read_events by event_type to prevent projection stalls ([#373](#373)) ### Features - add load-testing/stress-testing suite ([#370](#370)) </blockquote> ## `eventcore-sqlite` <blockquote> ## [0.7.1](eventcore-sqlite-v0.7.0...eventcore-sqlite-v0.7.1) - 2026-04-15 ### Bug Fixes - filter read_events by event_type to prevent projection stalls ([#373](#373)) </blockquote> ## `eventcore` <blockquote> ## [0.7.1](eventcore-v0.7.0...eventcore-v0.7.1) - 2026-04-15 ### Bug Fixes - filter read_events by event_type to prevent projection stalls ([#373](#373)) ### Features - add load-testing/stress-testing suite ([#370](#370)) </blockquote> ## `eventcore-memory` <blockquote> ## [0.7.1](eventcore-memory-v0.7.0...eventcore-memory-v0.7.1) - 2026-04-15 ### Bug Fixes - filter read_events by event_type to prevent projection stalls ([#373](#373)) </blockquote> ## `eventcore-testing` <blockquote> ## [0.7.1](eventcore-testing-v0.7.0...eventcore-testing-v0.7.1) - 2026-04-15 ### Features - add load-testing/stress-testing suite ([#370](#370)) </blockquote> ## `eventcore-examples` <blockquote> ## [0.7.0](eventcore-examples-v0.6.0...eventcore-examples-v0.7.0) - 2026-04-13 ### Bug Fixes - improve error message consistency, context, and safety across all crates ([#352](#352)) ### Features - add required event_type_name() to Event trait for stable storage ([#344](#344)) - add TestScenario GWT testing helpers to eventcore-testing ([#346](#346)) ### Miscellaneous Tasks - consolidate workspace lints and enforce strict lint policy ([#351](#351)) ### Refactoring - replace into_inner() with into() for nutype domain types ([#334](#334)) - expose projection config via free function API, then reduce public surface ([#357](#357)) </blockquote> </p></details> --- This PR was generated with [release-plz](https://github.com/release-plz/release-plz/).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Comprehensive error message consistency audit and fixes across all 8 EventCore crates. Closes #243.
Changes
EventStoreError::VersionConflictnow carriesstream_id,expected, andactualfields instead of being a bare unit variant with no context.expect()in SQLiteappend_events()andtry_acquire_lock()with properResult-based error handlingsubscription_namein leadership error messagesInMemoryCheckpointError,InMemoryCoordinationError,NoCheckpointError, andContractTestFailurefrom manualimpl Displayto#[derive(thiserror::Error)]single_stream_command_test.rsnow uses typedWithdrawErrorenum withFromimpl instead of directCommandError::BusinessRuleViolation(format!(...))Not changed (intentional)
CommandError::BusinessRuleViolation(String)and itsFrom<String>/From<&str>impls — intentional design for therequire!macroProjectionError::Failed(String)structure — would require pipeline refactoring beyond audit scopeEventStoreError::StoreFailuredetail field — needs deeper architectural thought about error source chainsTest plan
cargo nextest run --workspace)cargo clippy --all-targets --all-features -- -D warnings)cargo fmt --all --check).claude/rules/— no violations