diff --git a/eventhandler/projector/eventhandler.go b/eventhandler/projector/eventhandler.go index 792bfe92..8c9907b2 100644 --- a/eventhandler/projector/eventhandler.go +++ b/eventhandler/projector/eventhandler.go @@ -124,6 +124,11 @@ func (h *EventHandler) HandleEvent(ctx context.Context, event eh.Event) error { // The entity should be one version behind the event. if entity, ok := entity.(eh.Versionable); ok { + // Ignore old/duplicate events. + if entity.AggregateVersion() >= event.Version() { + return nil + } + if entity.AggregateVersion()+1 != event.Version() { return Error{ Err: eh.ErrIncorrectEntityVersion, diff --git a/eventhandler/projector/eventhandler_test.go b/eventhandler/projector/eventhandler_test.go index 1a07528c..d30e8889 100644 --- a/eventhandler/projector/eventhandler_test.go +++ b/eventhandler/projector/eventhandler_test.go @@ -99,6 +99,11 @@ func TestEventHandler_UpdateModel(t *testing.T) { if repo.Entity != projector.newEntity { t.Error("the new entity should be correct:", repo.Entity) } + + // Handle event again, should be a no-op. + if err := handler.HandleEvent(ctx, event); err != nil { + t.Error("there shoud be no error:", err) + } } func TestEventHandler_UpdateModelWithVersion(t *testing.T) { @@ -137,6 +142,11 @@ func TestEventHandler_UpdateModelWithVersion(t *testing.T) { if repo.Entity != projector.newEntity { t.Error("the new entity should be correct:", repo.Entity) } + + // Handle event again, should be a no-op. + if err := handler.HandleEvent(ctx, event); err != nil { + t.Error("there shoud be no error:", err) + } } func TestEventHandler_UpdateModelWithEventsOutOfOrder(t *testing.T) {