public async Task When_using_Update_then_failed_writes_are_logged_to_EventHandlingErrors() { // preload some events for the catchup. replay will hit the barrier on the last one. var order = new Order(); var productName = Any.Paragraph(4); order.Apply(new AddItem { Quantity = 1, ProductName = productName, Price = .01m }); var repository = new SqlEventSourcedRepository <Order>(new FakeEventBus()); await repository.Save(order); Projector1 projector = null; projector = new Projector1 { OnUpdate = (_, e) => { using (var work = projector.Update()) { var db = work.Resource <ReadModelDbContext>(); // do something that will trigger a db exception when the UnitOfWork is committed var inventory = db.Set <ProductInventory>(); inventory.Add(new ProductInventory { ProductName = e.ProductName, QuantityReserved = e.Quantity }); inventory.Add(new ProductInventory { ProductName = e.ProductName, QuantityReserved = e.Quantity }); work.VoteCommit(); } } }; // act using (var catchup = CreateReadModelCatchup(projector)) { await catchup.Run(); } // assert using (var db = new ReadModelDbContext()) { var error = db.Set <EventHandlingError>().Single(e => e.AggregateId == order.Id); error.Error.Should() .Contain( string.Format( "Violation of PRIMARY KEY constraint 'PK_dbo.ProductInventories'. Cannot insert duplicate key in object 'dbo.ProductInventories'. The duplicate key value is ({0})", productName)); } }
public async Task When_using_Update_then_failed_writes_do_not_interrupt_catchup() { // preload some events for the catchup. replay will hit the barrier on the last one. var order = new Order(); var productName = Any.Paragraph(4); Action addEvent = () => order.Apply(new AddItem { Quantity = 1, ProductName = productName, Price = .01m }); Enumerable.Range(1, 30).ForEach(_ => addEvent()); var repository = new SqlEventSourcedRepository <Order>(new FakeEventBus()); await repository.Save(order); var count = 0; Projector1 projector = null; projector = new Projector1 { OnUpdate = (_, e) => { using (var work = projector.Update()) { var db = work.Resource <ReadModelDbContext>(); if (count++ == 15) { // do something that will trigger a db exception when the UnitOfWork is committed var inventory = db.Set <ProductInventory>(); inventory.Add(new ProductInventory { ProductName = e.ProductName, QuantityReserved = e.Quantity }); inventory.Add(new ProductInventory { ProductName = e.ProductName, QuantityReserved = e.Quantity }); } work.VoteCommit(); } } }; // act using (var catchup = CreateReadModelCatchup(projector)) { await catchup.Run(); } // assert count.Should().Be(30); }