setResiliencyMode(ResiliencyMode::FAIL_FAST); $provider->addListener('stdClass', function() { throw new \RuntimeException('Test Error'); }); $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('Test Error'); $dispatcher->dispatch(new \stdClass()); } public function test_it_continues_and_reports_in_continue_mode(): void { $provider = new ListenerProvider(); $dispatcher = new EventDispatcher($provider); $dispatcher->setResiliencyMode(ResiliencyMode::CONTINUE); $failedCount = 0; $listenersRun = 0; // Listener that fails $provider->addListener('stdClass', function() { throw new \RuntimeException('Test Error'); }); // Next listener that should still run $provider->addListener('stdClass', function() use (&$listenersRun) { $listenersRun++; }); // Error reporter listener $provider->addListener(DispatchFailed::class, function(DispatchFailed $event) use (&$failedCount) { $failedCount++; $this->assertEquals('Test Error', $event->getException()->getMessage()); }); $dispatcher->dispatch(new \stdClass()); $this->assertEquals(1, $listenersRun); $this->assertEquals(1, $failedCount); } public function test_event_envelope_carries_context(): void { $event = new \stdClass(); $context = ['request_id' => '123']; $envelope = new EventEnvelope($event, $context); $this->assertSame($event, $envelope->getEvent()); $this->assertEquals($context, $envelope->getContext()); } }