From c578ffe2ff124752853ceccc8267294c445fbf16 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 3 Nov 2017 09:25:38 +0100 Subject: [PATCH 01/25] Bump requirements in composer.json --- composer.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index 5b3a472c..5997ee85 100644 --- a/composer.json +++ b/composer.json @@ -19,19 +19,19 @@ "sort-packages": true }, "require": { - "php": "^5.6|^7.0", + "php": "^7.1", "sentry/sentry": "^1.7", - "symfony/config": "^2.7|^3.0", - "symfony/console": "^2.7|^3.0", - "symfony/dependency-injection": "^2.7|^3.0", - "symfony/event-dispatcher": "^2.7|^3.0", - "symfony/http-kernel": "^2.7|^3.0", - "symfony/security-core": "^2.7|^3.0", - "symfony/yaml": "^2.7|^3.0" + "symfony/config": "^3.0||^4.0", + "symfony/console": "^3.0||^4.0", + "symfony/dependency-injection": "^3.0||^4.0", + "symfony/event-dispatcher": "^3.0||^4.0", + "symfony/http-kernel": "^3.0||^4.0", + "symfony/security-core": "^3.0||^4.0", + "symfony/yaml": "^3.0||^4.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.5", - "phpunit/phpunit": "^5.7|^6.0", + "phpunit/phpunit": "^6.0", "scrutinizer/ocular": "^1.4" }, "autoload": { @@ -46,7 +46,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } } } From 01575b54900636962a56698313162e553f241b19 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 3 Nov 2017 09:42:06 +0100 Subject: [PATCH 02/25] Update Travis to reflect the new version contraints --- .travis.yml | 21 +++++++-------------- composer.json | 4 +++- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index ae72a5e2..d05d8e3f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,6 @@ sudo: false dist: trusty php: - - 5.6 - - 7.0 - 7.1 - 7.2 @@ -13,34 +11,29 @@ cache: - $HOME/.composer/cache/files before_install: + - phpenv config-rm xdebug.ini - composer self-update - composer global require hirak/prestissimo - - if [[ $TRAVIS_PHP_VERSION = '7.2' ]]; then composer remove --dev friendsofphp/php-cs-fixer --no-update --no-interaction; fi -install: travis_wait travis_retry composer update --no-interaction --prefer-dist --prefer-stable $COMPOSER_OPTIONS +install: + - travis_wait travis_retry composer update --no-interaction --prefer-dist --prefer-stable $COMPOSER_OPTIONS script: - vendor/bin/phpunit -v jobs: include: - - stage: test - php: 5.6 - env: COMPOSER_OPTIONS="--prefer-lowest" - stage: Test - php: 7.0 - env: COMPOSER_OPTIONS="--prefer-lowest" - - stage: codestyle and SCA php: 7.1 + env: COMPOSER_OPTIONS="--prefer-lowest" + - stage: Code style and static analysis script: - - phpenv config-rm xdebug.ini - - composer require --dev phpstan/phpstan symfony/expression-language --no-interaction --prefer-dist --prefer-stable - vendor/bin/phpstan analyse src --level 7 env: PHPSTAN=true - - script: vendor/bin/php-cs-fixer fix --verbose --diff --dry-run + - script: + - vendor/bin/php-cs-fixer fix --verbose --diff --dry-run env: CS-FIXER=true - stage: coverage - php: 7.1 script: - phpdbg -qrr vendor/bin/phpunit --coverage-clover clover.xml after_success: diff --git a/composer.json b/composer.json index 5997ee85..729e1733 100644 --- a/composer.json +++ b/composer.json @@ -31,8 +31,10 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.5", + "phpstan/phpstan": "^0.8.5", "phpunit/phpunit": "^6.0", - "scrutinizer/ocular": "^1.4" + "scrutinizer/ocular": "^1.4", + "symfony/expression-language ": "^3.0||^4.0" }, "autoload": { "psr-4" : { From 4f2b021a4c33752fea3999dda8373546d5549c83 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 3 Nov 2017 09:45:28 +0100 Subject: [PATCH 03/25] Fix typo in composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 729e1733..edcec62a 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "phpstan/phpstan": "^0.8.5", "phpunit/phpunit": "^6.0", "scrutinizer/ocular": "^1.4", - "symfony/expression-language ": "^3.0||^4.0" + "symfony/expression-language": "^3.0||^4.0" }, "autoload": { "psr-4" : { From d772535b193f313c9fbd216953edf8eaf6b243f3 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 3 Nov 2017 09:55:52 +0100 Subject: [PATCH 04/25] Add types where possibile; require symfony/console 3.3+ due to ConsoleErrorEvent --- composer.json | 2 +- src/DependencyInjection/Configuration.php | 10 ++-------- src/ErrorTypesParser.php | 13 ++++++++----- src/Event/SentryUserContextEvent.php | 3 ++- src/EventListener/ExceptionListener.php | 8 ++++---- .../SentryExceptionListenerInterface.php | 6 +++--- src/SentrySymfonyClient.php | 2 +- 7 files changed, 21 insertions(+), 23 deletions(-) diff --git a/composer.json b/composer.json index edcec62a..c24a206b 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "php": "^7.1", "sentry/sentry": "^1.7", "symfony/config": "^3.0||^4.0", - "symfony/console": "^3.0||^4.0", + "symfony/console": "^3.3||^4.0", "symfony/dependency-injection": "^3.0||^4.0", "symfony/event-dispatcher": "^3.0||^4.0", "symfony/http-kernel": "^3.0||^4.0", diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 49a5d3cd..c8896e3a 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -138,10 +138,7 @@ public function getConfigTreeBuilder() return $treeBuilder; } - /** - * @return \Closure - */ - private function getExceptionListenerInvalidationClosure() + private function getExceptionListenerInvalidationClosure(): callable { return function ($value) { $implements = class_implements($value); @@ -153,10 +150,7 @@ private function getExceptionListenerInvalidationClosure() }; } - /** - * @return \Closure - */ - private function getTrimClosure() + private function getTrimClosure(): callable { return function ($str) { $value = trim($str); diff --git a/src/ErrorTypesParser.php b/src/ErrorTypesParser.php index fa037352..a5c21950 100644 --- a/src/ErrorTypesParser.php +++ b/src/ErrorTypesParser.php @@ -7,14 +7,15 @@ */ class ErrorTypesParser { - private $expression = null; + /** @var string */ + private $expression; /** * Initialize ErrorParser * * @param string $expression Error Types e.g. E_ALL & ~E_DEPRECATED & ~E_NOTICE */ - public function __construct($expression) + public function __construct(string $expression) { $this->expression = $expression; } @@ -23,8 +24,9 @@ public function __construct($expression) * Parse and compute the error types expression * * @return int the parsed expression + * @throws \InvalidArgumentException */ - public function parse() + public function parse(): int { // convert constants to ints $this->expression = $this->convertErrorConstants($this->expression); @@ -43,7 +45,7 @@ public function parse() * @param string $expression e.g. E_ALL & ~E_DEPRECATED & ~E_NOTICE * @return string converted expression e.g. 32767 & ~8192 & ~8 */ - private function convertErrorConstants($expression) + private function convertErrorConstants(string $expression): string { $output = preg_replace_callback('/(E_[a-zA-Z_]+)/', function ($errorConstant) { if (defined($errorConstant[1])) { @@ -61,8 +63,9 @@ private function convertErrorConstants($expression) * * @param string $expression prepared expression e.g. 32767&~8192&~8 * @return int computed expression e.g. 24567 + * @throws \InvalidArgumentException */ - private function compute($expression) + private function compute(string $expression): int { // catch anything which could be a security issue if (0 !== preg_match("/[^\d.+*%^|&~<>\/()-]/", $this->expression)) { diff --git a/src/Event/SentryUserContextEvent.php b/src/Event/SentryUserContextEvent.php index ff9fd255..5369908b 100644 --- a/src/Event/SentryUserContextEvent.php +++ b/src/Event/SentryUserContextEvent.php @@ -7,6 +7,7 @@ class SentryUserContextEvent extends Event { + /** @var TokenInterface */ private $authenticationToken; public function __construct(TokenInterface $authenticationToken) @@ -14,7 +15,7 @@ public function __construct(TokenInterface $authenticationToken) $this->authenticationToken = $authenticationToken; } - public function getAuthenticationToken() + public function getAuthenticationToken(): TokenInterface { return $this->authenticationToken; } diff --git a/src/EventListener/ExceptionListener.php b/src/EventListener/ExceptionListener.php index 5b878f08..84080691 100644 --- a/src/EventListener/ExceptionListener.php +++ b/src/EventListener/ExceptionListener.php @@ -5,7 +5,7 @@ use Sentry\SentryBundle\Event\SentryUserContextEvent; use Sentry\SentryBundle\SentrySymfonyEvents; use Symfony\Component\Console\Event\ConsoleCommandEvent; -use Symfony\Component\Console\Event\ConsoleExceptionEvent; +use Symfony\Component\Console\Event\ConsoleErrorEvent; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; @@ -71,7 +71,7 @@ public function setClient(\Raven_Client $client) * * @param GetResponseEvent $event */ - public function onKernelRequest(GetResponseEvent $event) + public function onKernelRequest(GetResponseEvent $event): void { if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { return; @@ -120,9 +120,9 @@ public function onConsoleCommand(ConsoleCommandEvent $event) } /** - * @param ConsoleExceptionEvent $event + * @param ConsoleErrorEvent $event */ - public function onConsoleException(ConsoleExceptionEvent $event) + public function onConsoleException(ConsoleErrorEvent $event) { $command = $event->getCommand(); $exception = $event->getException(); diff --git a/src/EventListener/SentryExceptionListenerInterface.php b/src/EventListener/SentryExceptionListenerInterface.php index 7f91f526..159766da 100644 --- a/src/EventListener/SentryExceptionListenerInterface.php +++ b/src/EventListener/SentryExceptionListenerInterface.php @@ -2,7 +2,7 @@ namespace Sentry\SentryBundle\EventListener; -use Symfony\Component\Console\Event\ConsoleExceptionEvent; +use Symfony\Component\Console\Event\ConsoleErrorEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; @@ -31,7 +31,7 @@ public function onKernelException(GetResponseForExceptionEvent $event); * When an exception occurs on the command line, this method will be * triggered for capturing the error. * - * @param ConsoleExceptionEvent $event + * @param ConsoleErrorEvent $event */ - public function onConsoleException(ConsoleExceptionEvent $event); + public function onConsoleException(ConsoleErrorEvent $event); } diff --git a/src/SentrySymfonyClient.php b/src/SentrySymfonyClient.php index 723d6c37..0589d9de 100644 --- a/src/SentrySymfonyClient.php +++ b/src/SentrySymfonyClient.php @@ -4,7 +4,7 @@ class SentrySymfonyClient extends \Raven_Client { - public function __construct($dsn = null, $options = []) + public function __construct(?string $dsn = null, array $options = []) { if (! empty($options['error_types'])) { $exParser = new ErrorTypesParser($options['error_types']); From 0eef5640eec1be9387ed785c3c5c79df6a22d4c7 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 3 Nov 2017 10:03:33 +0100 Subject: [PATCH 05/25] Use jean85/pretty-package-versions to show the correct version of the bundle --- composer.json | 1 + src/SentryBundle.php | 7 ++++++- src/SentrySymfonyClient.php | 2 +- test/SentrySymfonyClientTest.php | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index c24a206b..4b3c3d1c 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,7 @@ }, "require": { "php": "^7.1", + "jean85/pretty-package-versions": "^1.0", "sentry/sentry": "^1.7", "symfony/config": "^3.0||^4.0", "symfony/console": "^3.3||^4.0", diff --git a/src/SentryBundle.php b/src/SentryBundle.php index 3403d1bc..fa563a96 100644 --- a/src/SentryBundle.php +++ b/src/SentryBundle.php @@ -2,9 +2,14 @@ namespace Sentry\SentryBundle; +use Jean85\PrettyVersions; use Symfony\Component\HttpKernel\Bundle\Bundle; class SentryBundle extends Bundle { - const VERSION = '1.0-dev'; + public static function getVersion(): string + { + return PrettyVersions::getVersion('sentry/sentry-symfony') + ->getPrettyVersion(); + } } diff --git a/src/SentrySymfonyClient.php b/src/SentrySymfonyClient.php index 0589d9de..69e33531 100644 --- a/src/SentrySymfonyClient.php +++ b/src/SentrySymfonyClient.php @@ -13,7 +13,7 @@ public function __construct(?string $dsn = null, array $options = []) $options['sdk'] = [ 'name' => 'sentry-symfony', - 'version' => SentryBundle::VERSION, + 'version' => SentryBundle::getVersion(), ]; parent::__construct($dsn, $options); diff --git a/test/SentrySymfonyClientTest.php b/test/SentrySymfonyClientTest.php index 8f82fa80..af7c52a7 100644 --- a/test/SentrySymfonyClientTest.php +++ b/test/SentrySymfonyClientTest.php @@ -15,7 +15,7 @@ public function test_that_it_sets_sdk_name_and_version() $data = $client->get_default_data(); $this->assertEquals('sentry-symfony', $data['sdk']['name']); - $this->assertEquals(SentryBundle::VERSION, $data['sdk']['version']); + $this->assertEquals(SentryBundle::getVersion(), $data['sdk']['version']); } public function test_that_it_forwards_options() From 7181a2a7aea38e9f58fb7f95ff2635f28de505e3 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 3 Nov 2017 10:09:01 +0100 Subject: [PATCH 06/25] Update changelog --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93ddc142..2bbeb5a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +## 2.0.0 - [Unreleased] +### Added + - Add support for Symfony 4.x +### Changed + - The `SentryBundle::VERSION` constant has been replaced with the `SentryBundle::getVersion(): string` method, to get a more accurate result + - Due to a deprecation in `symfony/console`, we require it at at least version 3.3, and we made this change to the `SentryExceptionListenerInterface`: +```php + // before + public function onConsoleException(ConsoleExceptionEvent $event); + // after + public function onConsoleException(ConsoleErrorEvent $event); +``` +### Removed + - Drop support for Symfony 2.x + - Drop support for PHP 5 and 7.0 + ## 1.0.0 - [Unreleased] ### Added - Add official support to PHP 7.2 (#71) From 482be86ddaf1e245bc4a36fdcb26ebf057e5f1bd Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 3 Nov 2017 10:10:35 +0100 Subject: [PATCH 07/25] Fix unit test --- test/EventListener/ExceptionListenerTest.php | 189 +++++++------------ 1 file changed, 64 insertions(+), 125 deletions(-) diff --git a/test/EventListener/ExceptionListenerTest.php b/test/EventListener/ExceptionListenerTest.php index 9c18e52b..22b26e05 100644 --- a/test/EventListener/ExceptionListenerTest.php +++ b/test/EventListener/ExceptionListenerTest.php @@ -8,6 +8,7 @@ use Sentry\SentryBundle\EventListener\ExceptionListener; use Sentry\SentryBundle\SentrySymfonyEvents; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Event\ConsoleErrorEvent; use Symfony\Component\Console\Event\ConsoleExceptionEvent; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -75,20 +76,17 @@ public function test_that_user_data_is_not_set_on_subrequest() $mockEvent ->expects($this->once()) ->method('getRequestType') - ->willReturn(HttpKernelInterface::SUB_REQUEST) - ; + ->willReturn(HttpKernelInterface::SUB_REQUEST); $this->mockSentryClient ->expects($this->never()) ->method('set_user_data') - ->withAnyParameters() - ; + ->withAnyParameters(); $this->mockEventDispatcher ->expects($this->never()) ->method('dispatch') - ->withAnyParameters() - ; + ->withAnyParameters(); $this->containerBuilder->compile(); $listener = $this->containerBuilder->get('sentry.exception_listener'); @@ -104,20 +102,17 @@ public function test_that_user_data_is_not_set_if_token_storage_not_present() $mockEvent ->expects($this->once()) ->method('getRequestType') - ->willReturn(HttpKernelInterface::MASTER_REQUEST) - ; + ->willReturn(HttpKernelInterface::MASTER_REQUEST); $this->mockSentryClient ->expects($this->never()) ->method('set_user_data') - ->withAnyParameters() - ; + ->withAnyParameters(); $this->mockEventDispatcher ->expects($this->never()) ->method('dispatch') - ->withAnyParameters() - ; + ->withAnyParameters(); $this->assertFalse($this->containerBuilder->has('security.token_storage')); @@ -136,20 +131,17 @@ public function test_that_user_data_is_not_set_if_authorization_checker_not_pres $mockEvent ->expects($this->once()) ->method('getRequestType') - ->willReturn(HttpKernelInterface::MASTER_REQUEST) - ; + ->willReturn(HttpKernelInterface::MASTER_REQUEST); $this->mockSentryClient ->expects($this->never()) ->method('set_user_data') - ->withAnyParameters() - ; + ->withAnyParameters(); $this->mockEventDispatcher ->expects($this->never()) ->method('dispatch') - ->withAnyParameters() - ; + ->withAnyParameters(); $this->containerBuilder->compile(); @@ -170,31 +162,26 @@ public function test_that_user_data_is_not_set_if_token_not_present() $mockEvent ->expects($this->once()) ->method('getRequestType') - ->willReturn(HttpKernelInterface::MASTER_REQUEST) - ; + ->willReturn(HttpKernelInterface::MASTER_REQUEST); $this->mockAuthorizationChecker ->method('isGranted') ->with($this->identicalTo(AuthenticatedVoter::IS_AUTHENTICATED_REMEMBERED)) - ->willReturn(true) - ; + ->willReturn(true); $this->mockTokenStorage ->method('getToken') - ->willReturn(null) - ; + ->willReturn(null); $this->mockSentryClient ->expects($this->never()) ->method('set_user_data') - ->withAnyParameters() - ; + ->withAnyParameters(); $this->mockEventDispatcher ->expects($this->never()) ->method('dispatch') - ->withAnyParameters() - ; + ->withAnyParameters(); $this->containerBuilder->compile(); $listener = $this->containerBuilder->get('sentry.exception_listener'); @@ -210,38 +197,32 @@ public function test_that_user_data_is_not_set_if_not_authorized() $mockToken ->method('getUser') - ->willReturn($user) - ; + ->willReturn($user); $mockEvent = $this->createMock(GetResponseEvent::class); $mockEvent->expects($this->once()) ->method('getRequestType') - ->willReturn(HttpKernelInterface::MASTER_REQUEST) - ; + ->willReturn(HttpKernelInterface::MASTER_REQUEST); $this->mockAuthorizationChecker ->method('isGranted') ->with($this->identicalTo(AuthenticatedVoter::IS_AUTHENTICATED_REMEMBERED)) - ->willReturn(false) - ; + ->willReturn(false); $this->mockTokenStorage ->method('getToken') - ->willReturn($mockToken) - ; + ->willReturn($mockToken); $this->mockSentryClient ->expects($this->never()) ->method('set_user_data') - ->withAnyParameters() - ; + ->withAnyParameters(); $this->mockEventDispatcher ->expects($this->never()) ->method('dispatch') - ->withAnyParameters() - ; + ->withAnyParameters(); $this->containerBuilder->compile(); $listener = $this->containerBuilder->get('sentry.exception_listener'); @@ -257,40 +238,34 @@ public function test_that_username_is_set_from_user_interface_if_token_present_a $mockToken ->method('getUser') - ->willReturn($user) - ; + ->willReturn($user); $mockToken ->method('isAuthenticated') - ->willReturn(true) - ; + ->willReturn(true); $mockEvent = $this->createMock(GetResponseEvent::class); $mockEvent ->expects($this->once()) ->method('getRequestType') - ->willReturn(HttpKernelInterface::MASTER_REQUEST) - ; + ->willReturn(HttpKernelInterface::MASTER_REQUEST); $this ->mockAuthorizationChecker ->method('isGranted') ->with($this->identicalTo(AuthenticatedVoter::IS_AUTHENTICATED_REMEMBERED)) - ->willReturn(true) - ; + ->willReturn(true); $this->mockTokenStorage ->method('getToken') - ->willReturn($mockToken) - ; + ->willReturn($mockToken); $this ->mockSentryClient ->expects($this->once()) ->method('set_user_data') - ->with($this->identicalTo('username')) - ; + ->with($this->identicalTo('username')); $this ->mockEventDispatcher @@ -299,8 +274,7 @@ public function test_that_username_is_set_from_user_interface_if_token_present_a ->with( $this->identicalTo(SentrySymfonyEvents::SET_USER_CONTEXT), $this->isInstanceOf(SentryUserContextEvent::class) - ) - ; + ); $this->containerBuilder->compile(); $listener = $this->containerBuilder->get('sentry.exception_listener'); @@ -313,38 +287,32 @@ public function test_that_username_is_set_from_user_interface_if_token_present_a $mockToken ->method('getUser') - ->willReturn('some_user') - ; + ->willReturn('some_user'); $mockToken ->method('isAuthenticated') - ->willReturn(true) - ; + ->willReturn(true); $mockEvent = $this->createMock(GetResponseEvent::class); $mockEvent ->expects($this->once()) ->method('getRequestType') - ->willReturn(HttpKernelInterface::MASTER_REQUEST) - ; + ->willReturn(HttpKernelInterface::MASTER_REQUEST); $this->mockAuthorizationChecker ->method('isGranted') ->with($this->identicalTo(AuthenticatedVoter::IS_AUTHENTICATED_REMEMBERED)) - ->willReturn(true) - ; + ->willReturn(true); $this->mockTokenStorage ->method('getToken') - ->willReturn($mockToken) - ; + ->willReturn($mockToken); $this->mockSentryClient ->expects($this->once()) ->method('set_user_data') - ->with($this->identicalTo('some_user')) - ; + ->with($this->identicalTo('some_user')); $this->mockEventDispatcher ->expects($this->once()) @@ -352,8 +320,7 @@ public function test_that_username_is_set_from_user_interface_if_token_present_a ->with( $this->identicalTo(SentrySymfonyEvents::SET_USER_CONTEXT), $this->isInstanceOf(SentryUserContextEvent::class) - ) - ; + ); $this->containerBuilder->compile(); $listener = $this->containerBuilder->get('sentry.exception_listener'); @@ -364,51 +331,43 @@ public function test_that_username_is_set_from_user_interface_if_token_present_a { $mockUser = $this->getMockBuilder('stdClass') ->setMethods(['__toString']) - ->getMock() - ; + ->getMock(); $mockUser ->expects($this->once()) ->method('__toString') - ->willReturn('std_user') - ; + ->willReturn('std_user'); $mockToken = $this->createMock(TokenInterface::class); $mockToken ->method('getUser') - ->willReturn($mockUser) - ; + ->willReturn($mockUser); $mockToken ->method('isAuthenticated') - ->willReturn(true) - ; + ->willReturn(true); $mockEvent = $this->createMock(GetResponseEvent::class); $mockEvent ->expects($this->once()) ->method('getRequestType') - ->willReturn(HttpKernelInterface::MASTER_REQUEST) - ; + ->willReturn(HttpKernelInterface::MASTER_REQUEST); $this->mockAuthorizationChecker ->method('isGranted') ->with($this->identicalTo(AuthenticatedVoter::IS_AUTHENTICATED_REMEMBERED)) - ->willReturn(true) - ; + ->willReturn(true); $this->mockTokenStorage ->method('getToken') - ->willReturn($mockToken) - ; + ->willReturn($mockToken); $this->mockSentryClient ->expects($this->once()) ->method('set_user_data') - ->with($this->identicalTo('std_user')) - ; + ->with($this->identicalTo('std_user')); $this->mockEventDispatcher ->expects($this->once()) @@ -416,8 +375,7 @@ public function test_that_username_is_set_from_user_interface_if_token_present_a ->with( $this->identicalTo(SentrySymfonyEvents::SET_USER_CONTEXT), $this->isInstanceOf(SentryUserContextEvent::class) - ) - ; + ); $this->containerBuilder->compile(); $listener = $this->containerBuilder->get('sentry.exception_listener'); @@ -429,21 +387,18 @@ public function test_regression_with_unauthenticated_user_token_PR_78() $mockToken = $this->createMock(TokenInterface::class); $mockToken ->method('isAuthenticated') - ->willReturn(false) - ; + ->willReturn(false); $mockEvent = $this->createMock(GetResponseEvent::class); $mockEvent ->expects($this->once()) ->method('getRequestType') - ->willReturn(HttpKernelInterface::MASTER_REQUEST) - ; + ->willReturn(HttpKernelInterface::MASTER_REQUEST); $this->mockTokenStorage ->method('getToken') - ->willReturn($mockToken) - ; + ->willReturn($mockToken); $this->containerBuilder->compile(); $listener = $this->containerBuilder->get('sentry.exception_listener'); @@ -457,20 +412,17 @@ public function test_that_it_does_not_report_http_exception_if_included_in_captu $mockEvent ->expects($this->once()) ->method('getException') - ->willReturn(new HttpException(401)) - ; + ->willReturn(new HttpException(401)); $this->mockEventDispatcher ->expects($this->never()) ->method('dispatch') - ->withAnyParameters() - ; + ->withAnyParameters(); $this->mockSentryClient ->expects($this->never()) ->method('captureException') - ->withAnyParameters() - ; + ->withAnyParameters(); $this->containerBuilder->compile(); $listener = $this->containerBuilder->get('sentry.exception_listener'); @@ -485,20 +437,17 @@ public function test_that_it_captures_exception() $mockEvent ->expects($this->once()) ->method('getException') - ->willReturn($reportableException) - ; + ->willReturn($reportableException); $this->mockEventDispatcher ->expects($this->once()) ->method('dispatch') - ->with($this->identicalTo(SentrySymfonyEvents::PRE_CAPTURE), $this->identicalTo($mockEvent)) - ; + ->with($this->identicalTo(SentrySymfonyEvents::PRE_CAPTURE), $this->identicalTo($mockEvent)); $this->mockSentryClient ->expects($this->once()) ->method('captureException') - ->with($this->identicalTo($reportableException)) - ; + ->with($this->identicalTo($reportableException)); $this->containerBuilder->compile(); $listener = $this->containerBuilder->get('sentry.exception_listener'); @@ -512,31 +461,27 @@ public function test_that_it_captures_console_exception(Command $mockCommand = n { $reportableException = new \Exception(); - $mockEvent = $this->createMock(ConsoleExceptionEvent::class); + $mockEvent = $this->createMock(ConsoleErrorEvent::class); $mockEvent ->expects($this->once()) ->method('getExitCode') - ->willReturn(10) - ; + ->willReturn(10); $mockEvent ->expects($this->once()) ->method('getException') - ->willReturn($reportableException) - ; + ->willReturn($reportableException); $mockEvent ->expects($this->once()) ->method('getCommand') - ->willReturn($mockCommand) - ; + ->willReturn($mockCommand); $this->mockEventDispatcher ->expects($this->once()) ->method('dispatch') - ->with($this->identicalTo(SentrySymfonyEvents::PRE_CAPTURE), $this->identicalTo($mockEvent)) - ; + ->with($this->identicalTo(SentrySymfonyEvents::PRE_CAPTURE), $this->identicalTo($mockEvent)); $this->mockSentryClient ->expects($this->once()) @@ -549,8 +494,7 @@ public function test_that_it_captures_console_exception(Command $mockCommand = n 'status_code' => 10, ], ]) - ) - ; + ); $this->containerBuilder->compile(); $listener = $this->containerBuilder->get('sentry.exception_listener'); @@ -563,8 +507,7 @@ public function mockCommandProvider() $mockCommand ->expects($this->once()) ->method('getName') - ->willReturn('cmd name') - ; + ->willReturn('cmd name'); return [ [$mockCommand, 'cmd name'], @@ -583,26 +526,22 @@ public function test_that_it_can_replace_client() $mockEvent ->expects($this->once()) ->method('getException') - ->willReturn($reportableException) - ; + ->willReturn($reportableException); $this->mockEventDispatcher ->expects($this->once()) ->method('dispatch') - ->with($this->identicalTo(SentrySymfonyEvents::PRE_CAPTURE), $this->identicalTo($mockEvent)) - ; + ->with($this->identicalTo(SentrySymfonyEvents::PRE_CAPTURE), $this->identicalTo($mockEvent)); $this->mockSentryClient ->expects($this->never()) ->method('captureException') - ->withAnyParameters() - ; + ->withAnyParameters(); $replacementClient ->expects($this->once()) ->method('captureException') - ->with($this->identicalTo($reportableException)) - ; + ->with($this->identicalTo($reportableException)); $this->containerBuilder->compile(); $listener = $this->containerBuilder->get('sentry.exception_listener'); From fe8ff7b3a0b832ed4513de12abde847d4ef56c3e Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 3 Nov 2017 10:32:42 +0100 Subject: [PATCH 08/25] Refactor and fix onConsoleException --- src/EventListener/ExceptionListener.php | 4 +-- test/EventListener/ExceptionListenerTest.php | 37 +++++++++----------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/EventListener/ExceptionListener.php b/src/EventListener/ExceptionListener.php index 84080691..3f387549 100644 --- a/src/EventListener/ExceptionListener.php +++ b/src/EventListener/ExceptionListener.php @@ -125,7 +125,7 @@ public function onConsoleCommand(ConsoleCommandEvent $event) public function onConsoleException(ConsoleErrorEvent $event) { $command = $event->getCommand(); - $exception = $event->getException(); + $exception = $event->getError(); if ($this->shouldExceptionCaptureBeSkipped($exception)) { return; @@ -142,7 +142,7 @@ public function onConsoleException(ConsoleErrorEvent $event) $this->client->captureException($exception, $data); } - protected function shouldExceptionCaptureBeSkipped(\Exception $exception) + protected function shouldExceptionCaptureBeSkipped(\Throwable $exception) { foreach ($this->skipCapture as $className) { if ($exception instanceof $className) { diff --git a/test/EventListener/ExceptionListenerTest.php b/test/EventListener/ExceptionListenerTest.php index 22b26e05..1cfa0317 100644 --- a/test/EventListener/ExceptionListenerTest.php +++ b/test/EventListener/ExceptionListenerTest.php @@ -6,10 +6,13 @@ use Sentry\SentryBundle\DependencyInjection\SentryExtension; use Sentry\SentryBundle\Event\SentryUserContextEvent; use Sentry\SentryBundle\EventListener\ExceptionListener; +use Sentry\SentryBundle\EventListener\SentryExceptionListenerInterface; use Sentry\SentryBundle\SentrySymfonyEvents; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Event\ConsoleErrorEvent; use Symfony\Component\Console\Event\ConsoleExceptionEvent; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; @@ -457,37 +460,28 @@ public function test_that_it_captures_exception() /** * @dataProvider mockCommandProvider */ - public function test_that_it_captures_console_exception(Command $mockCommand = null, $expectedCommandName) + public function test_that_it_captures_console_exception(?Command $mockCommand, string $expectedCommandName) { - $reportableException = new \Exception(); - - $mockEvent = $this->createMock(ConsoleErrorEvent::class); + $error = $this->createMock(\Error::class); - $mockEvent - ->expects($this->once()) - ->method('getExitCode') - ->willReturn(10); - - $mockEvent - ->expects($this->once()) - ->method('getException') - ->willReturn($reportableException); - - $mockEvent - ->expects($this->once()) - ->method('getCommand') - ->willReturn($mockCommand); + $event = new ConsoleErrorEvent( + $this->createMock(InputInterface::class), + $this->createMock(OutputInterface::class), + $error, + $mockCommand + ); + $event->setExitCode(10); $this->mockEventDispatcher ->expects($this->once()) ->method('dispatch') - ->with($this->identicalTo(SentrySymfonyEvents::PRE_CAPTURE), $this->identicalTo($mockEvent)); + ->with($this->identicalTo(SentrySymfonyEvents::PRE_CAPTURE), $this->identicalTo($event)); $this->mockSentryClient ->expects($this->once()) ->method('captureException') ->with( - $this->identicalTo($reportableException), + $this->identicalTo($error), $this->identicalTo([ 'tags' => [ 'command' => $expectedCommandName, @@ -497,8 +491,9 @@ public function test_that_it_captures_console_exception(Command $mockCommand = n ); $this->containerBuilder->compile(); + /** @var SentryExceptionListenerInterface $listener */ $listener = $this->containerBuilder->get('sentry.exception_listener'); - $listener->onConsoleException($mockEvent); + $listener->onConsoleException($event); } public function mockCommandProvider() From 275ce2096f54ff8ee28ee26c8bc3456ea379a01e Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 3 Nov 2017 10:39:48 +0100 Subject: [PATCH 09/25] Increase and fix PHPStan checks --- .travis.yml | 2 +- src/EventListener/ExceptionListener.php | 1 + test/EventListener/ExceptionListenerTest.php | 11 +++++------ 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index d05d8e3f..fd6ccbfa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ jobs: env: COMPOSER_OPTIONS="--prefer-lowest" - stage: Code style and static analysis script: - - vendor/bin/phpstan analyse src --level 7 + - vendor/bin/phpstan analyse src test --level 7 env: PHPSTAN=true - script: - vendor/bin/php-cs-fixer fix --verbose --diff --dry-run diff --git a/src/EventListener/ExceptionListener.php b/src/EventListener/ExceptionListener.php index 3f387549..77ce15c6 100644 --- a/src/EventListener/ExceptionListener.php +++ b/src/EventListener/ExceptionListener.php @@ -125,6 +125,7 @@ public function onConsoleCommand(ConsoleCommandEvent $event) public function onConsoleException(ConsoleErrorEvent $event) { $command = $event->getCommand(); + /** @var \Exception $exception to avoid issues with PHPStan */ $exception = $event->getError(); if ($this->shouldExceptionCaptureBeSkipped($exception)) { diff --git a/test/EventListener/ExceptionListenerTest.php b/test/EventListener/ExceptionListenerTest.php index 1cfa0317..7a1f597f 100644 --- a/test/EventListener/ExceptionListenerTest.php +++ b/test/EventListener/ExceptionListenerTest.php @@ -463,13 +463,12 @@ public function test_that_it_captures_exception() public function test_that_it_captures_console_exception(?Command $mockCommand, string $expectedCommandName) { $error = $this->createMock(\Error::class); + /** @var InputInterface $input */ + $input = $this->createMock(InputInterface::class); + /** @var OutputInterface $output */ + $output = $this->createMock(OutputInterface::class); - $event = new ConsoleErrorEvent( - $this->createMock(InputInterface::class), - $this->createMock(OutputInterface::class), - $error, - $mockCommand - ); + $event = new ConsoleErrorEvent($input, $output, $error, $mockCommand); $event->setExitCode(10); $this->mockEventDispatcher From 6c365c5cb0ae5c56dd3d9eeae926eb61613db537 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 3 Nov 2017 10:50:06 +0100 Subject: [PATCH 10/25] Fix code style --- test/EventListener/ExceptionListenerTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/test/EventListener/ExceptionListenerTest.php b/test/EventListener/ExceptionListenerTest.php index 7a1f597f..90699125 100644 --- a/test/EventListener/ExceptionListenerTest.php +++ b/test/EventListener/ExceptionListenerTest.php @@ -10,7 +10,6 @@ use Sentry\SentryBundle\SentrySymfonyEvents; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Event\ConsoleErrorEvent; -use Symfony\Component\Console\Event\ConsoleExceptionEvent; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; From ae712c4d1d2f38d42f94a34304239d17baeeeaad Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Tue, 7 Nov 2017 09:25:06 +0100 Subject: [PATCH 11/25] Mark version as 1.0 and tag it --- CHANGELOG.md | 2 +- src/SentryBundle.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db301798..3b31b760 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] -## 1.0.0 - [Unreleased] +## 1.0.0 - 2017-11-07 ### Added - Add official support to PHP 7.2 (#71) ### Changed diff --git a/src/SentryBundle.php b/src/SentryBundle.php index 3403d1bc..6df2762d 100644 --- a/src/SentryBundle.php +++ b/src/SentryBundle.php @@ -6,5 +6,5 @@ class SentryBundle extends Bundle { - const VERSION = '1.0-dev'; + const VERSION = '1.0'; } From 30fab0c34f41eb13ea3669daf5d737966b4e9cab Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Tue, 7 Nov 2017 09:33:09 +0100 Subject: [PATCH 12/25] Mark correct bundle dev versions --- composer.json | 4 +++- src/SentryBundle.php | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 8f1579ae..e68e4aab 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,9 @@ }, "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "master": "2.0.x-dev", + "releases/0.8.x": "0.8.x-dev", + "releases/1.x": "1.0.x-dev" } } } diff --git a/src/SentryBundle.php b/src/SentryBundle.php index 6df2762d..2c60f5bc 100644 --- a/src/SentryBundle.php +++ b/src/SentryBundle.php @@ -6,5 +6,5 @@ class SentryBundle extends Bundle { - const VERSION = '1.0'; + const VERSION = '1.0.x-dev'; } From fbdca2f7055d82815c3e6557e7773fa95813c4d0 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Tue, 7 Nov 2017 09:33:09 +0100 Subject: [PATCH 13/25] Mark correct bundle dev versions (cherry picked from commit 30fab0c) --- composer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4b3c3d1c..9ff95ec2 100644 --- a/composer.json +++ b/composer.json @@ -49,7 +49,9 @@ }, "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "master": "2.0.x-dev", + "releases/0.8.x": "0.8.x-dev", + "releases/1.x": "1.0.x-dev" } } } From bbc2c9b842567724a8aaa221e0ba264523ef7ddc Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Mon, 4 Dec 2017 13:01:43 +0100 Subject: [PATCH 14/25] Make client service public --- src/Resources/config/services.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Resources/config/services.yml b/src/Resources/config/services.yml index 213c8be5..c6849f48 100644 --- a/src/Resources/config/services.yml +++ b/src/Resources/config/services.yml @@ -2,6 +2,7 @@ services: sentry.client: class: '%sentry.client%' arguments: ['%sentry.dsn%', '%sentry.options%'] + public: true calls: - [install, []] From 2e65e7658b7d64ed3c6158257508debc80ddfd25 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Mon, 4 Dec 2017 15:25:48 +0100 Subject: [PATCH 15/25] Define a public alias in test for the listener --- .../SentryExtensionTest.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/test/DependencyInjection/SentryExtensionTest.php b/test/DependencyInjection/SentryExtensionTest.php index 73482c6e..ff662349 100644 --- a/test/DependencyInjection/SentryExtensionTest.php +++ b/test/DependencyInjection/SentryExtensionTest.php @@ -5,9 +5,12 @@ use PHPUnit\Framework\TestCase; use Sentry\SentryBundle\DependencyInjection\SentryExtension; use Sentry\SentryBundle\EventListener\ExceptionListener; +use Sentry\SentryBundle\EventListener\SentryExceptionListenerInterface; use Sentry\SentryBundle\SentrySymfonyClient; use Sentry\SentryBundle\Test\Fixtures\CustomExceptionListener; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; @@ -15,6 +18,7 @@ class SentryExtensionTest extends TestCase { const SUPPORTED_SENTRY_OPTIONS_COUNT = 34; + const LISTENER_TEST_PUBLIC_ALIAS = 'sentry.exception_listener.public_alias'; public function test_that_configuration_uses_the_right_default_values() { @@ -258,8 +262,8 @@ public function test_that_it_has_sentry_client_service_and_it_defaults_to_symfon public function test_that_it_has_sentry_exception_listener_and_it_defaults_to_default_exception_listener() { - $client = $this->getContainer()->get('sentry.exception_listener'); - $this->assertInstanceOf(ExceptionListener::class, $client); + $listener = $this->getContainer()->get(self::LISTENER_TEST_PUBLIC_ALIAS); + $this->assertInstanceOf(ExceptionListener::class, $listener); } public function test_that_it_has_proper_event_listener_tags_for_exception_listener() @@ -347,7 +351,8 @@ public function test_that_it_sets_all_sentry_options() $this->assertCount(self::SUPPORTED_SENTRY_OPTIONS_COUNT, $options); $defaultOptions = $this->getContainer()->getParameter('sentry.options'); foreach ($options as $name => $value) { - $this->assertNotEquals($defaultOptions[$name], $value, 'Test precondition failed: using default value for ' . $name); + $this->assertNotEquals($defaultOptions[$name], $value, + 'Test precondition failed: using default value for ' . $name); } $container = $this->getContainer(['options' => $options]); @@ -355,11 +360,7 @@ public function test_that_it_sets_all_sentry_options() $this->assertSame($options, $container->getParameter('sentry.options')); } - /** - * @param array $configuration - * @return ContainerBuilder - */ - private function getContainer(array $configuration = []) + private function getContainer(array $configuration = []): Container { $containerBuilder = new ContainerBuilder(); $containerBuilder->setParameter('kernel.root_dir', 'kernel/root'); @@ -369,6 +370,7 @@ private function getContainer(array $configuration = []) ->createMock(EventDispatcherInterface::class); $containerBuilder->set('event_dispatcher', $mockEventDispatcher); + $containerBuilder->setAlias(self::LISTENER_TEST_PUBLIC_ALIAS, new Alias('sentry.exception_listener')); $extension = new SentryExtension(); $extension->load(['sentry' => $configuration], $containerBuilder); From 9aff0de67a6740b3213f0ff7622969528f7e4e31 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Mon, 4 Dec 2017 15:50:54 +0100 Subject: [PATCH 16/25] Fix listener tests --- .../SentryExtensionTest.php | 4 +- test/EventListener/ExceptionListenerTest.php | 39 ++++++++++++------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/test/DependencyInjection/SentryExtensionTest.php b/test/DependencyInjection/SentryExtensionTest.php index ff662349..30e5637b 100644 --- a/test/DependencyInjection/SentryExtensionTest.php +++ b/test/DependencyInjection/SentryExtensionTest.php @@ -17,8 +17,8 @@ class SentryExtensionTest extends TestCase { - const SUPPORTED_SENTRY_OPTIONS_COUNT = 34; - const LISTENER_TEST_PUBLIC_ALIAS = 'sentry.exception_listener.public_alias'; + private const SUPPORTED_SENTRY_OPTIONS_COUNT = 34; + private const LISTENER_TEST_PUBLIC_ALIAS = 'sentry.exception_listener.public_alias'; public function test_that_configuration_uses_the_right_default_values() { diff --git a/test/EventListener/ExceptionListenerTest.php b/test/EventListener/ExceptionListenerTest.php index 90699125..376a2fe3 100644 --- a/test/EventListener/ExceptionListenerTest.php +++ b/test/EventListener/ExceptionListenerTest.php @@ -12,6 +12,7 @@ use Symfony\Component\Console\Event\ConsoleErrorEvent; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; @@ -26,6 +27,8 @@ class ExceptionListenerTest extends TestCase { + private const LISTENER_TEST_PUBLIC_ALIAS = 'sentry.exception_listener.public_alias'; + /** @var ContainerBuilder|\PHPUnit_Framework_MockObject_MockObject */ private $containerBuilder; @@ -56,6 +59,7 @@ public function setUp() $containerBuilder->set('security.authorization_checker', $this->mockAuthorizationChecker); $containerBuilder->set('sentry.client', $this->mockSentryClient); $containerBuilder->set('event_dispatcher', $this->mockEventDispatcher); + $containerBuilder->setAlias(self::LISTENER_TEST_PUBLIC_ALIAS, new Alias('sentry.exception_listener')); $extension = new SentryExtension(); $extension->load([], $containerBuilder); @@ -66,7 +70,7 @@ public function setUp() public function test_that_it_is_an_instance_of_sentry_exception_listener() { $this->containerBuilder->compile(); - $listener = $this->containerBuilder->get('sentry.exception_listener'); + $listener = $this->getListener(); $this->assertInstanceOf(ExceptionListener::class, $listener); } @@ -91,7 +95,7 @@ public function test_that_user_data_is_not_set_on_subrequest() ->withAnyParameters(); $this->containerBuilder->compile(); - $listener = $this->containerBuilder->get('sentry.exception_listener'); + $listener = $this->getListener(); $listener->onKernelRequest($mockEvent); } @@ -120,7 +124,7 @@ public function test_that_user_data_is_not_set_if_token_storage_not_present() $this->containerBuilder->compile(); - $listener = $this->containerBuilder->get('sentry.exception_listener'); + $listener = $this->getListener(); $listener->onKernelRequest($mockEvent); } @@ -149,7 +153,7 @@ public function test_that_user_data_is_not_set_if_authorization_checker_not_pres $this->assertFalse($this->containerBuilder->has('security.authorization_checker')); - $listener = $this->containerBuilder->get('sentry.exception_listener'); + $listener = $this->getListener(); $listener->onKernelRequest($mockEvent); } @@ -186,7 +190,7 @@ public function test_that_user_data_is_not_set_if_token_not_present() ->withAnyParameters(); $this->containerBuilder->compile(); - $listener = $this->containerBuilder->get('sentry.exception_listener'); + $listener = $this->getListener(); $listener->onKernelRequest($mockEvent); } @@ -227,7 +231,7 @@ public function test_that_user_data_is_not_set_if_not_authorized() ->withAnyParameters(); $this->containerBuilder->compile(); - $listener = $this->containerBuilder->get('sentry.exception_listener'); + $listener = $this->getListener(); $listener->onKernelRequest($mockEvent); } @@ -279,7 +283,7 @@ public function test_that_username_is_set_from_user_interface_if_token_present_a ); $this->containerBuilder->compile(); - $listener = $this->containerBuilder->get('sentry.exception_listener'); + $listener = $this->getListener(); $listener->onKernelRequest($mockEvent); } @@ -325,7 +329,7 @@ public function test_that_username_is_set_from_user_interface_if_token_present_a ); $this->containerBuilder->compile(); - $listener = $this->containerBuilder->get('sentry.exception_listener'); + $listener = $this->getListener(); $listener->onKernelRequest($mockEvent); } @@ -380,7 +384,7 @@ public function test_that_username_is_set_from_user_interface_if_token_present_a ); $this->containerBuilder->compile(); - $listener = $this->containerBuilder->get('sentry.exception_listener'); + $listener = $this->getListener(); $listener->onKernelRequest($mockEvent); } @@ -403,7 +407,7 @@ public function test_regression_with_unauthenticated_user_token_PR_78() ->willReturn($mockToken); $this->containerBuilder->compile(); - $listener = $this->containerBuilder->get('sentry.exception_listener'); + $listener = $this->getListener(); $listener->onKernelRequest($mockEvent); } @@ -427,7 +431,7 @@ public function test_that_it_does_not_report_http_exception_if_included_in_captu ->withAnyParameters(); $this->containerBuilder->compile(); - $listener = $this->containerBuilder->get('sentry.exception_listener'); + $listener = $this->getListener(); $listener->onKernelException($mockEvent); } @@ -452,7 +456,7 @@ public function test_that_it_captures_exception() ->with($this->identicalTo($reportableException)); $this->containerBuilder->compile(); - $listener = $this->containerBuilder->get('sentry.exception_listener'); + $listener = $this->getListener(); $listener->onKernelException($mockEvent); } @@ -490,7 +494,7 @@ public function test_that_it_captures_console_exception(?Command $mockCommand, s $this->containerBuilder->compile(); /** @var SentryExceptionListenerInterface $listener */ - $listener = $this->containerBuilder->get('sentry.exception_listener'); + $listener = $this->getListener(); $listener->onConsoleException($event); } @@ -537,10 +541,17 @@ public function test_that_it_can_replace_client() ->with($this->identicalTo($reportableException)); $this->containerBuilder->compile(); - $listener = $this->containerBuilder->get('sentry.exception_listener'); + /** @var ExceptionListener $listener */ + $listener = $this->getListener(); + $this->assertInstanceOf(ExceptionListener::class, $listener); $listener->setClient($replacementClient); $listener->onKernelException($mockEvent); } + + private function getListener(): SentryExceptionListenerInterface + { + return $this->containerBuilder->get(self::LISTENER_TEST_PUBLIC_ALIAS); + } } From 16519d2ab174f4c745c9b8a35f2aea962d591881 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Mon, 4 Dec 2017 16:04:34 +0100 Subject: [PATCH 17/25] Mark explicitly as public test aliases --- test/DependencyInjection/SentryExtensionTest.php | 3 +-- test/EventListener/ExceptionListenerTest.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/test/DependencyInjection/SentryExtensionTest.php b/test/DependencyInjection/SentryExtensionTest.php index 30e5637b..f759aee1 100644 --- a/test/DependencyInjection/SentryExtensionTest.php +++ b/test/DependencyInjection/SentryExtensionTest.php @@ -5,7 +5,6 @@ use PHPUnit\Framework\TestCase; use Sentry\SentryBundle\DependencyInjection\SentryExtension; use Sentry\SentryBundle\EventListener\ExceptionListener; -use Sentry\SentryBundle\EventListener\SentryExceptionListenerInterface; use Sentry\SentryBundle\SentrySymfonyClient; use Sentry\SentryBundle\Test\Fixtures\CustomExceptionListener; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; @@ -370,7 +369,7 @@ private function getContainer(array $configuration = []): Container ->createMock(EventDispatcherInterface::class); $containerBuilder->set('event_dispatcher', $mockEventDispatcher); - $containerBuilder->setAlias(self::LISTENER_TEST_PUBLIC_ALIAS, new Alias('sentry.exception_listener')); + $containerBuilder->setAlias(self::LISTENER_TEST_PUBLIC_ALIAS, new Alias('sentry.exception_listener', true)); $extension = new SentryExtension(); $extension->load(['sentry' => $configuration], $containerBuilder); diff --git a/test/EventListener/ExceptionListenerTest.php b/test/EventListener/ExceptionListenerTest.php index 376a2fe3..66f6055d 100644 --- a/test/EventListener/ExceptionListenerTest.php +++ b/test/EventListener/ExceptionListenerTest.php @@ -59,7 +59,7 @@ public function setUp() $containerBuilder->set('security.authorization_checker', $this->mockAuthorizationChecker); $containerBuilder->set('sentry.client', $this->mockSentryClient); $containerBuilder->set('event_dispatcher', $this->mockEventDispatcher); - $containerBuilder->setAlias(self::LISTENER_TEST_PUBLIC_ALIAS, new Alias('sentry.exception_listener')); + $containerBuilder->setAlias(self::LISTENER_TEST_PUBLIC_ALIAS, new Alias('sentry.exception_listener', true)); $extension = new SentryExtension(); $extension->load([], $containerBuilder); From faf4c4ef87face76571a5ff2e3b881f3a08a9988 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Mon, 4 Dec 2017 16:29:24 +0100 Subject: [PATCH 18/25] Fix CS; update PHPStan; put commands in composer.json --- .travis.yml | 4 ++-- composer.json | 7 ++++++- test/DependencyInjection/SentryExtensionTest.php | 7 +++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index fd6ccbfa..b404917d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,10 +28,10 @@ jobs: env: COMPOSER_OPTIONS="--prefer-lowest" - stage: Code style and static analysis script: - - vendor/bin/phpstan analyse src test --level 7 + - composer phpstan env: PHPSTAN=true - script: - - vendor/bin/php-cs-fixer fix --verbose --diff --dry-run + - composer cs-check env: CS-FIXER=true - stage: coverage script: diff --git a/composer.json b/composer.json index 2d26e8e2..b59c9e9e 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.5", - "phpstan/phpstan": "^0.8.5", + "phpstan/phpstan": "^0.9.1", "phpunit/phpunit": "^6.0", "scrutinizer/ocular": "^1.4", "symfony/expression-language": "^3.0||^4.0" @@ -47,6 +47,11 @@ "Sentry\\SentryBundle\\Test\\": "test" } }, + "scripts": { + "phpstan": "vendor/bin/phpstan analyse src test --level 7 -c phpstan.neon", + "cs-check": "vendor/bin/php-cs-fixer fix --verbose --diff --dry-run", + "cs-fix": "vendor/bin/php-cs-fixer fix --verbose --diff" + }, "extra": { "branch-alias": { "master": "2.0.x-dev", diff --git a/test/DependencyInjection/SentryExtensionTest.php b/test/DependencyInjection/SentryExtensionTest.php index f759aee1..858ba5b8 100644 --- a/test/DependencyInjection/SentryExtensionTest.php +++ b/test/DependencyInjection/SentryExtensionTest.php @@ -350,8 +350,11 @@ public function test_that_it_sets_all_sentry_options() $this->assertCount(self::SUPPORTED_SENTRY_OPTIONS_COUNT, $options); $defaultOptions = $this->getContainer()->getParameter('sentry.options'); foreach ($options as $name => $value) { - $this->assertNotEquals($defaultOptions[$name], $value, - 'Test precondition failed: using default value for ' . $name); + $this->assertNotEquals( + $defaultOptions[$name], + $value, + 'Test precondition failed: using default value for ' . $name + ); } $container = $this->getContainer(['options' => $options]); From c270dbd66dc7305be5f27f71f61836300cc3ce16 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Mon, 4 Dec 2017 15:44:21 +0100 Subject: [PATCH 19/25] Fix or ignore PHPStan errors (cherry picked from commit c93be40) --- phpstan.neon | 4 ++++ src/DependencyInjection/Configuration.php | 3 +++ src/EventListener/ExceptionListener.php | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 phpstan.neon diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 00000000..4be52564 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,4 @@ +parameters: + ignoreErrors: + - '/Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface::/' + - '/Calling method \w+ on possibly null value of type Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface|null/' diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index c8896e3a..7e8dce85 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -6,6 +6,8 @@ use Sentry\SentryBundle\EventListener\ExceptionListener; use Sentry\SentryBundle\EventListener\SentryExceptionListenerInterface; use Sentry\SentryBundle\SentrySymfonyClient; +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; @@ -25,6 +27,7 @@ class Configuration implements ConfigurationInterface public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); + /** @var ArrayNodeDefinition $rootNode */ $rootNode = $treeBuilder->root('sentry'); // Basic Sentry configuration diff --git a/src/EventListener/ExceptionListener.php b/src/EventListener/ExceptionListener.php index 77ce15c6..a67e4509 100644 --- a/src/EventListener/ExceptionListener.php +++ b/src/EventListener/ExceptionListener.php @@ -172,7 +172,7 @@ private function setUserValue($user) } if (is_object($user) && method_exists($user, '__toString')) { - $this->client->set_user_data($user->__toString()); + $this->client->set_user_data((string)$user); } } } From dbb1318fa3df81a5e65b6a4fee90022404b88a9e Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Mon, 4 Dec 2017 16:37:57 +0100 Subject: [PATCH 20/25] Add PHPStan PHPUnit extension --- composer.json | 1 + phpstan.neon | 2 ++ src/DependencyInjection/Configuration.php | 1 - test/EventListener/ExceptionListenerTest.php | 7 +------ 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index b59c9e9e..36d1986a 100644 --- a/composer.json +++ b/composer.json @@ -33,6 +33,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "^2.5", "phpstan/phpstan": "^0.9.1", + "phpstan/phpstan-phpunit": "^0.9.1", "phpunit/phpunit": "^6.0", "scrutinizer/ocular": "^1.4", "symfony/expression-language": "^3.0||^4.0" diff --git a/phpstan.neon b/phpstan.neon index 4be52564..94862647 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,3 +2,5 @@ parameters: ignoreErrors: - '/Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface::/' - '/Calling method \w+ on possibly null value of type Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface|null/' +includes: + - vendor/phpstan/phpstan-phpunit/extension.neon diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 7e8dce85..662534fb 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -7,7 +7,6 @@ use Sentry\SentryBundle\EventListener\SentryExceptionListenerInterface; use Sentry\SentryBundle\SentrySymfonyClient; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; -use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; diff --git a/test/EventListener/ExceptionListenerTest.php b/test/EventListener/ExceptionListenerTest.php index 66f6055d..c5e66dc1 100644 --- a/test/EventListener/ExceptionListenerTest.php +++ b/test/EventListener/ExceptionListenerTest.php @@ -29,19 +29,14 @@ class ExceptionListenerTest extends TestCase { private const LISTENER_TEST_PUBLIC_ALIAS = 'sentry.exception_listener.public_alias'; - /** @var ContainerBuilder|\PHPUnit_Framework_MockObject_MockObject */ private $containerBuilder; - /** @var \Raven_Client|\PHPUnit_Framework_MockObject_MockObject */ private $mockSentryClient; - /** @var TokenStorageInterface|\PHPUnit_Framework_MockObject_MockObject */ private $mockTokenStorage; - /** @var AuthorizationCheckerInterface|\PHPUnit_Framework_MockObject_MockObject */ private $mockAuthorizationChecker; - /** @var EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject */ private $mockEventDispatcher; public function setUp() @@ -514,7 +509,7 @@ public function mockCommandProvider() public function test_that_it_can_replace_client() { - $replacementClient = $this->createMock('Raven_Client'); + $replacementClient = $this->createMock(\Raven_Client::class); $reportableException = new \Exception(); From 0e5fd353fb4c86f02228ee9dc62aedf0fdd26be0 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Mon, 4 Dec 2017 16:42:30 +0100 Subject: [PATCH 21/25] Bump minimum PHPUnit and CS Fixer required version --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 36d1986a..ff1efce6 100644 --- a/composer.json +++ b/composer.json @@ -31,10 +31,10 @@ "symfony/yaml": "^3.0||^4.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.5", + "friendsofphp/php-cs-fixer": "^2.8", "phpstan/phpstan": "^0.9.1", "phpstan/phpstan-phpunit": "^0.9.1", - "phpunit/phpunit": "^6.0", + "phpunit/phpunit": "^6.5", "scrutinizer/ocular": "^1.4", "symfony/expression-language": "^3.0||^4.0" }, From 132b469571310606b87d86146ffe80c10d0a8c02 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Thu, 7 Dec 2017 16:03:29 +0100 Subject: [PATCH 22/25] Add missing return types --- src/EventListener/ExceptionListener.php | 6 +++--- src/EventListener/SentryExceptionListenerInterface.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/EventListener/ExceptionListener.php b/src/EventListener/ExceptionListener.php index a67e4509..c7bb2954 100644 --- a/src/EventListener/ExceptionListener.php +++ b/src/EventListener/ExceptionListener.php @@ -94,7 +94,7 @@ public function onKernelRequest(GetResponseEvent $event): void /** * @param GetResponseForExceptionEvent $event */ - public function onKernelException(GetResponseForExceptionEvent $event) + public function onKernelException(GetResponseForExceptionEvent $event): void { $exception = $event->getException(); @@ -114,7 +114,7 @@ public function onKernelException(GetResponseForExceptionEvent $event) * * @return void */ - public function onConsoleCommand(ConsoleCommandEvent $event) + public function onConsoleCommand(ConsoleCommandEvent $event): void { // only triggers loading of client, does not need to do anything. } @@ -122,7 +122,7 @@ public function onConsoleCommand(ConsoleCommandEvent $event) /** * @param ConsoleErrorEvent $event */ - public function onConsoleException(ConsoleErrorEvent $event) + public function onConsoleException(ConsoleErrorEvent $event): void { $command = $event->getCommand(); /** @var \Exception $exception to avoid issues with PHPStan */ diff --git a/src/EventListener/SentryExceptionListenerInterface.php b/src/EventListener/SentryExceptionListenerInterface.php index 159766da..4fa98a83 100644 --- a/src/EventListener/SentryExceptionListenerInterface.php +++ b/src/EventListener/SentryExceptionListenerInterface.php @@ -17,7 +17,7 @@ interface SentryExceptionListenerInterface * * @param GetResponseEvent $event */ - public function onKernelRequest(GetResponseEvent $event); + public function onKernelRequest(GetResponseEvent $event): void; /** * When an exception occurs as part of a web request, this method will be @@ -25,7 +25,7 @@ public function onKernelRequest(GetResponseEvent $event); * * @param GetResponseForExceptionEvent $event */ - public function onKernelException(GetResponseForExceptionEvent $event); + public function onKernelException(GetResponseForExceptionEvent $event): void; /** * When an exception occurs on the command line, this method will be @@ -33,5 +33,5 @@ public function onKernelException(GetResponseForExceptionEvent $event); * * @param ConsoleErrorEvent $event */ - public function onConsoleException(ConsoleErrorEvent $event); + public function onConsoleException(ConsoleErrorEvent $event): void; } From 4999bcdd14419fe2ee7c481b600bd712e883df8c Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Thu, 7 Dec 2017 16:35:41 +0100 Subject: [PATCH 23/25] Add last missing return type --- src/EventListener/ExceptionListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EventListener/ExceptionListener.php b/src/EventListener/ExceptionListener.php index c7bb2954..14c8d97b 100644 --- a/src/EventListener/ExceptionListener.php +++ b/src/EventListener/ExceptionListener.php @@ -143,7 +143,7 @@ public function onConsoleException(ConsoleErrorEvent $event): void $this->client->captureException($exception, $data); } - protected function shouldExceptionCaptureBeSkipped(\Throwable $exception) + protected function shouldExceptionCaptureBeSkipped(\Throwable $exception): bool { foreach ($this->skipCapture as $className) { if ($exception instanceof $className) { From 9681cb634c8e73bab402b7b137eb24bc3b03ad5a Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Tue, 12 Dec 2017 13:05:51 +0100 Subject: [PATCH 24/25] Add BC trick to avoid issues with Symfony 3.x --- CHANGELOG.md | 5 +-- src/EventListener/ExceptionListener.php | 29 +++++++++--- .../SentryExceptionListenerInterface.php | 12 ++++- src/Resources/config/services.yml | 39 ++++++++-------- .../SentryExtensionTest.php | 5 +++ test/EventListener/ExceptionListenerTest.php | 44 ++++++++++++++++++- 6 files changed, 103 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3955b06a..b5f3ae00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add support for Symfony 4.x ### Changed - The `SentryBundle::VERSION` constant has been replaced with the `SentryBundle::getVersion(): string` method, to get a more accurate result - - Due to a deprecation in `symfony/console`, we require it at at least version 3.3, and we made this change to the `SentryExceptionListenerInterface`: + - Due to a deprecation in `symfony/console`, we require it at at least version 3.3, and we added a method to `SentryExceptionListenerInterface`: ```php - // before - public function onConsoleException(ConsoleExceptionEvent $event); - // after public function onConsoleException(ConsoleErrorEvent $event); ``` ### Removed diff --git a/src/EventListener/ExceptionListener.php b/src/EventListener/ExceptionListener.php index 14c8d97b..d7948986 100644 --- a/src/EventListener/ExceptionListener.php +++ b/src/EventListener/ExceptionListener.php @@ -6,6 +6,8 @@ use Sentry\SentryBundle\SentrySymfonyEvents; use Symfony\Component\Console\Event\ConsoleCommandEvent; use Symfony\Component\Console\Event\ConsoleErrorEvent; +use Symfony\Component\Console\Event\ConsoleEvent; +use Symfony\Component\Console\Event\ConsoleExceptionEvent; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; @@ -119,14 +121,29 @@ public function onConsoleCommand(ConsoleCommandEvent $event): void // only triggers loading of client, does not need to do anything. } - /** - * @param ConsoleErrorEvent $event - */ - public function onConsoleException(ConsoleErrorEvent $event): void + public function onConsoleError(ConsoleErrorEvent $event): void + { + $this->handleConsoleError($event); + } + + public function onConsoleException(ConsoleExceptionEvent $event): void + { + $this->handleConsoleError($event); + } + + private function handleConsoleError(ConsoleEvent $event): void { $command = $event->getCommand(); - /** @var \Exception $exception to avoid issues with PHPStan */ - $exception = $event->getError(); + switch (true) { + case $event instanceof ConsoleErrorEvent: + $exception = $event->getError(); + break; + case $event instanceof ConsoleExceptionEvent: + $exception = $event->getException(); + break; + default: + throw new \InvalidArgumentException('Event not recognized: ' . \get_class($event)); + } if ($this->shouldExceptionCaptureBeSkipped($exception)) { return; diff --git a/src/EventListener/SentryExceptionListenerInterface.php b/src/EventListener/SentryExceptionListenerInterface.php index 4fa98a83..90246e3d 100644 --- a/src/EventListener/SentryExceptionListenerInterface.php +++ b/src/EventListener/SentryExceptionListenerInterface.php @@ -3,6 +3,7 @@ namespace Sentry\SentryBundle\EventListener; use Symfony\Component\Console\Event\ConsoleErrorEvent; +use Symfony\Component\Console\Event\ConsoleExceptionEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; @@ -33,5 +34,14 @@ public function onKernelException(GetResponseForExceptionEvent $event): void; * * @param ConsoleErrorEvent $event */ - public function onConsoleException(ConsoleErrorEvent $event): void; + public function onConsoleError(ConsoleErrorEvent $event): void; + + /** + * When an exception occurs on the command line, this method will be + * triggered for capturing the error. + * + * @param ConsoleErrorEvent $event + * @deprecated This method exists for BC with Symfony 3.x + */ + public function onConsoleException(ConsoleExceptionEvent $event): void; } diff --git a/src/Resources/config/services.yml b/src/Resources/config/services.yml index c6849f48..018b0612 100644 --- a/src/Resources/config/services.yml +++ b/src/Resources/config/services.yml @@ -1,21 +1,22 @@ services: - sentry.client: - class: '%sentry.client%' - arguments: ['%sentry.dsn%', '%sentry.options%'] - public: true - calls: - - [install, []] + sentry.client: + class: '%sentry.client%' + arguments: ['%sentry.dsn%', '%sentry.options%'] + public: true + calls: + - [install, []] - sentry.exception_listener: - class: '%sentry.exception_listener%' - arguments: - - '@sentry.client' - - '@event_dispatcher' - - '%sentry.skip_capture%' - - '@?security.token_storage' - - '@?security.authorization_checker' - tags: - - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%sentry.listener_priorities.request%'} - - { name: kernel.event_listener, event: kernel.exception, method: onKernelException, priority: '%sentry.listener_priorities.kernel_exception%' } - - { name: kernel.event_listener, event: console.command, method: onConsoleCommand } - - { name: kernel.event_listener, event: console.exception, method: onConsoleException, priority: '%sentry.listener_priorities.console_exception%' } + sentry.exception_listener: + class: '%sentry.exception_listener%' + arguments: + - '@sentry.client' + - '@event_dispatcher' + - '%sentry.skip_capture%' + - '@?security.token_storage' + - '@?security.authorization_checker' + tags: + - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%sentry.listener_priorities.request%'} + - { name: kernel.event_listener, event: kernel.exception, method: onKernelException, priority: '%sentry.listener_priorities.kernel_exception%' } + - { name: kernel.event_listener, event: console.command, method: onConsoleCommand } + - { name: kernel.event_listener, event: console.exception, method: onConsoleException, priority: '%sentry.listener_priorities.console_exception%' } + - { name: kernel.event_listener, event: console.error, method: onConsoleError, priority: '%sentry.listener_priorities.console_exception%' } diff --git a/test/DependencyInjection/SentryExtensionTest.php b/test/DependencyInjection/SentryExtensionTest.php index 858ba5b8..f5e1c6bb 100644 --- a/test/DependencyInjection/SentryExtensionTest.php +++ b/test/DependencyInjection/SentryExtensionTest.php @@ -292,6 +292,11 @@ public function test_that_it_has_proper_event_listener_tags_for_exception_listen 'method' => 'onConsoleException', 'priority' => '%sentry.listener_priorities.console_exception%', ], + [ + 'event' => 'console.error', + 'method' => 'onConsoleError', + 'priority' => '%sentry.listener_priorities.console_exception%', + ], ], $tags ); diff --git a/test/EventListener/ExceptionListenerTest.php b/test/EventListener/ExceptionListenerTest.php index c5e66dc1..b3cf8029 100644 --- a/test/EventListener/ExceptionListenerTest.php +++ b/test/EventListener/ExceptionListenerTest.php @@ -10,6 +10,7 @@ use Sentry\SentryBundle\SentrySymfonyEvents; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Event\ConsoleErrorEvent; +use Symfony\Component\Console\Event\ConsoleExceptionEvent; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\DependencyInjection\Alias; @@ -459,6 +460,47 @@ public function test_that_it_captures_exception() * @dataProvider mockCommandProvider */ public function test_that_it_captures_console_exception(?Command $mockCommand, string $expectedCommandName) + { + if (null === $mockCommand) { + $this->markTestSkipped('Command missing is not possibile with ConsoleExceptionEvent'); + } + + $exception = $this->createMock(\Exception::class); + /** @var InputInterface $input */ + $input = $this->createMock(InputInterface::class); + /** @var OutputInterface $output */ + $output = $this->createMock(OutputInterface::class); + + $event = new ConsoleExceptionEvent($mockCommand, $input, $output, $exception, 10); + + $this->mockEventDispatcher + ->expects($this->once()) + ->method('dispatch') + ->with($this->identicalTo(SentrySymfonyEvents::PRE_CAPTURE), $this->identicalTo($event)); + + $this->mockSentryClient + ->expects($this->once()) + ->method('captureException') + ->with( + $this->identicalTo($exception), + $this->identicalTo([ + 'tags' => [ + 'command' => $expectedCommandName, + 'status_code' => 10, + ], + ]) + ); + + $this->containerBuilder->compile(); + /** @var SentryExceptionListenerInterface $listener */ + $listener = $this->getListener(); + $listener->onConsoleException($event); + } + + /** + * @dataProvider mockCommandProvider + */ + public function test_that_it_captures_console_error(?Command $mockCommand, string $expectedCommandName) { $error = $this->createMock(\Error::class); /** @var InputInterface $input */ @@ -490,7 +532,7 @@ public function test_that_it_captures_console_exception(?Command $mockCommand, s $this->containerBuilder->compile(); /** @var SentryExceptionListenerInterface $listener */ $listener = $this->getListener(); - $listener->onConsoleException($event); + $listener->onConsoleError($event); } public function mockCommandProvider() From 3aaa5aff7a1769162be8df6de7b32572b2153edb Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Tue, 12 Dec 2017 14:24:50 +0100 Subject: [PATCH 25/25] Fix PHPStan errors --- src/EventListener/ExceptionListener.php | 3 +++ src/EventListener/SentryExceptionListenerInterface.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/EventListener/ExceptionListener.php b/src/EventListener/ExceptionListener.php index d7948986..ed239291 100644 --- a/src/EventListener/ExceptionListener.php +++ b/src/EventListener/ExceptionListener.php @@ -131,6 +131,9 @@ public function onConsoleException(ConsoleExceptionEvent $event): void $this->handleConsoleError($event); } + /** + * @param ConsoleExceptionEvent|ConsoleErrorEvent $event + */ private function handleConsoleError(ConsoleEvent $event): void { $command = $event->getCommand(); diff --git a/src/EventListener/SentryExceptionListenerInterface.php b/src/EventListener/SentryExceptionListenerInterface.php index 90246e3d..9d972074 100644 --- a/src/EventListener/SentryExceptionListenerInterface.php +++ b/src/EventListener/SentryExceptionListenerInterface.php @@ -40,7 +40,7 @@ public function onConsoleError(ConsoleErrorEvent $event): void; * When an exception occurs on the command line, this method will be * triggered for capturing the error. * - * @param ConsoleErrorEvent $event + * @param ConsoleExceptionEvent $event * @deprecated This method exists for BC with Symfony 3.x */ public function onConsoleException(ConsoleExceptionEvent $event): void;