diff --git a/_config/events.yml b/_config/events.yml index dd53f64..8d25876 100644 --- a/_config/events.yml +++ b/_config/events.yml @@ -8,12 +8,18 @@ SilverStripe\Core\Injector\Injector: ArchiPro\EventDispatcher\ListenerProvider: class: ArchiPro\EventDispatcher\ListenerProvider + # Define the error handler + ArchiPro\Silverstripe\EventDispatcher\ErrorHandling\ErrorHandler: + class: ArchiPro\Silverstripe\EventDispatcher\ErrorHandling\SilverstripeErrorHandler + constructor: + logger: '%$Psr\Log\LoggerInterface.errorhandler' + # Default event dispatcher ArchiPro\EventDispatcher\AsyncEventDispatcher: class: ArchiPro\EventDispatcher\AsyncEventDispatcher constructor: listenerProvider: '%$ArchiPro\EventDispatcher\ListenerProvider' - logger: '%$Psr\Log\LoggerInterface.errorhandler' + errorhandler: '%$ArchiPro\Silverstripe\EventDispatcher\ErrorHandling\ErrorHandler' Psr\EventDispatcher\EventDispatcherInterface: alias: '%$ArchiPro\EventDispatcher\AsyncEventDispatcher' diff --git a/composer.json b/composer.json index 7f5ab3e..a636ff4 100644 --- a/composer.json +++ b/composer.json @@ -15,8 +15,7 @@ "phpunit/phpunit": "^9.5", "squizlabs/php_codesniffer": "^3.0", "friendsofphp/php-cs-fixer": "^3.0", - "phpstan/phpstan": "^1.10", - "colinodell/psr-testlogger": "^1.3" + "phpstan/phpstan": "^1.10" }, "autoload": { "psr-4": { diff --git a/src/ErrorHandling/ErrorHandler.php b/src/ErrorHandling/ErrorHandler.php new file mode 100644 index 0000000..d4cbcd2 --- /dev/null +++ b/src/ErrorHandling/ErrorHandler.php @@ -0,0 +1,16 @@ +logger->error($error->getMessage(), ['exception' => $error]); + } +} \ No newline at end of file diff --git a/src/Service/TestEventService.php b/src/Service/TestEventService.php index 87ac8a5..75431ed 100644 --- a/src/Service/TestEventService.php +++ b/src/Service/TestEventService.php @@ -4,8 +4,10 @@ use ArchiPro\EventDispatcher\AsyncEventDispatcher; use ArchiPro\EventDispatcher\ListenerProvider; +use Closure; use ColinODell\PsrTestLogger\TestLogger; use SilverStripe\Core\Injector\Injector; +use Throwable; /** * Extension of the AsyncEventDispatcher for testing purposes. @@ -14,17 +16,18 @@ */ class TestEventService extends EventService { - private ?TestLogger $logger = null; - + /** + * @var array + */ + private array $errors = []; + public function __construct() { $listenerProvider = Injector::inst()->get(ListenerProvider::class); - - // The test logger is useful but we don't want to force people to install it in production. - if (class_exists(TestLogger::class)) { - $this->logger = new TestLogger(); - } - $dispatcher = new AsyncEventDispatcher($listenerProvider, $this->logger, AsyncEventDispatcher::THROW_ON_ERROR); + $dispatcher = new AsyncEventDispatcher( + $listenerProvider, + Closure::fromCallable([$this, 'recordError']) + ); parent::__construct($dispatcher, $listenerProvider); } @@ -39,16 +42,35 @@ public static function bootstrap(): self } /** - * Return a logger that can be used to see if an array errors were thrown by the event loop. + * Catch errors and store them for later inspection. + */ + private function recordError(Throwable $message): void + { + $this->errors[] = $message; + } + + /** + * Check if any errors were recorded. + */ + public function hasErrors(): bool + { + return !empty($this->errors); + } + + /** + * Get all errors that were recorded. + * @return array + */ + public function getErrors(): array + { + return $this->errors; + } + + /** + * Clear all errors. */ - public function getLogger(): TestLogger + public function clearErrors(): void { - if (!$this->logger) { - throw new \RuntimeException( - 'To use the EventService\'s test logger, you must install colinodell/psr-testlogger. ' . - '`composer require --dev colinodell/psr-testlogger`' - ); - } - return $this->logger; + $this->errors = []; } }