diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e68daf1..e0ea5ef 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - php: ['8.0', '8.1', '8.2', '8.3'] + php: ['8.0', '8.1', '8.2', '8.3', '8.4'] name: PHP ${{ matrix.php }} Test on ${{ matrix.os }} steps: - name: Checkout diff --git a/composer.json b/composer.json index 1ee0a4e..55043f2 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,11 @@ }, "require-dev": { "phpunit/phpunit": "^8.5|^9.0", - "phpstan/phpstan": "^1.10" + "phpstan/phpstan": "^1.10", + "sentry/sentry": "^3.0 || ^4.0" + }, + "suggest": { + "sentry/sentry": "Required to use the sentry middleware." }, "autoload": { "psr-4": { diff --git a/src/Middleware/SentryMiddleware.php b/src/Middleware/SentryMiddleware.php new file mode 100644 index 0000000..3c1c513 --- /dev/null +++ b/src/Middleware/SentryMiddleware.php @@ -0,0 +1,30 @@ + new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, handled: false), + ]); + + captureException($error, $hint); + + throw $error; + } + } +} diff --git a/tests/Middleware/SentryMiddlewareTest.php b/tests/Middleware/SentryMiddlewareTest.php new file mode 100644 index 0000000..c95c79f --- /dev/null +++ b/tests/Middleware/SentryMiddlewareTest.php @@ -0,0 +1,60 @@ +expects(self::never())->method('captureException'); + + $dispatcher = (new Builder()) + ->handle(Command\Hello::class, function () {}) + ->middleware(new SentryMiddleware()) + ->build(); + + $dispatcher->dispatch(new Command\Hello('onliner')); + } + + public function testCaptureErrors(): void + { + $hub = self::createMock(HubInterface::class); + SentrySdk::setCurrentHub($hub); + + $hint = EventHint::fromArray([ + 'mechanism' => new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, handled: false), + ]); + $e = new LogicException('expected'); + $hub->expects(self::once())->method('captureException')->with($e, $hint); + + $dispatcher = (new Builder()) + ->handle(Command\Hello::class, function () use ($e) { + throw $e; + }) + ->middleware(new SentryMiddleware()) + ->build(); + + $error = null; + + try { + $dispatcher->dispatch(new Command\Hello('onliner')); + } catch (LogicException $error) { + } + + self::assertNotNull($error); + } +}