diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 184fa62..c0fbc53 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -17,6 +17,8 @@ jobs: php: - "8.2" - "8.3" + - "8.4" + - "8.5" steps: - name: Checkout diff --git a/.github/workflows/docs-build.yml b/.github/workflows/docs-build.yml deleted file mode 100644 index 1a7aa24..0000000 --- a/.github/workflows/docs-build.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: docs-build - -on: - release: - types: [published] - workflow_dispatch: - -jobs: - build-deploy: - runs-on: ubuntu-latest - steps: - - name: Build Docs - uses: dotkernel/documentation-theme/github-actions/docs@main - env: - DEPLOY_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 0000000..9976515 --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,50 @@ +on: + - push + +name: Run PHPStan checks + +jobs: + mutation: + name: PHPStan ${{ matrix.php }}-${{ matrix.os }} + + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: + - ubuntu-latest + + php: + - "8.2" + - "8.3" + - "8.4" + - "8.5" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php }}" + coverage: pcov + ini-values: assert.exception=1, zend.assertions=1, error_reporting=-1, log_errors_max_len=0, display_errors=On + tools: composer:v2, cs2pr + + - name: Determine composer cache directory + run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV + + - name: Cache dependencies installed with composer + uses: actions/cache@v4 + with: + path: ${{ env.COMPOSER_CACHE_DIR }} + key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: | + php${{ matrix.php }}-composer- + + - name: Install dependencies with composer + run: composer install --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + + - name: Run static analysis with PHPStan + run: vendor/bin/phpstan analyse diff --git a/.laminas-ci.json b/.laminas-ci.json new file mode 100644 index 0000000..29216fa --- /dev/null +++ b/.laminas-ci.json @@ -0,0 +1,3 @@ +{ + "backwardCompatibilityCheck": true +} diff --git a/README.md b/README.md index 9b1a63e..99b55b6 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,22 @@ # dot-errorhandler -Error Logging Handler for DotKernel +Error Logging Handler for Dotkernel + +## Version History + +| Branch | Release | Service Manager | Log style implementation | PHP Version | +|--------|----------|-------------------|--------------------------|------------------------------------------------------------------------------------------------------------------| +| 4.0 | < 4.1.0 | Service Manager 3 | Laminas Log style | ![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-errorhandler/4.0.1) | +| 3.0 | < 4.0.0 | Service Manager 3 | Laminas Log | ![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-errorhandler/3.4.1) | + +## Documentation + +Documentation is available at: https://docs.dotkernel.org/dot-errorhandler/ + +## Badges ![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-errorhandler) -![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-errorhandler/4.0.0) +![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-errorhandler/4.0.1) [![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-errorhandler)](https://github.com/dotkernel/dot-errorhandler/issues) [![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-errorhandler)](https://github.com/dotkernel/dot-errorhandler/network) @@ -12,24 +25,27 @@ Error Logging Handler for DotKernel [![Build Static](https://github.com/dotkernel/dot-errorhandler/actions/workflows/continuous-integration.yml/badge.svg?branch=4.0)](https://github.com/dotkernel/dot-errorhandler/actions/workflows/continuous-integration.yml) [![codecov](https://codecov.io/gh/dotkernel/dot-errorhandler/branch/4.0/graph/badge.svg?token=0KIJARS5RS)](https://codecov.io/gh/dotkernel/dot-errorhandler) - -[![SymfonyInsight](https://insight.symfony.com/projects/cf1f8d89-f230-4157-bc8b-7cce20c75454/big.svg)](https://insight.symfony.com/projects/cf1f8d89-f230-4157-bc8b-7cce20c75454) +[![PHPStan](https://github.com/dotkernel/dot-errorhandler/actions/workflows/static-analysis.yml/badge.svg?branch=4.0)](https://github.com/dotkernel/dot-errorhandler/actions/workflows/static-analysis.yml) ## Adding the error handler -- Add the composer package: +- Add the Composer package. -`composer require dotkernel/dot-errorhandler` +```shell +composer require dotkernel/dot-errorhandler +``` - Add the config provider - in `config/config.php` add `\Dot\ErrorHandler\ConfigProvider` - in `config/pipeline.php` add `\Dot\ErrorHandler\ErrorHandlerInterface::class` - the interface is used as an alias to keep all error handling related configurations in one file - - **IMPORTANT NOTE** there should be no other error handlers after this one (only before) because the other error handler will catch the error causing dot-errorhandler not to catch any error, we recommend using just one error handler unless you have an error-specific handler -- Configure the error handler as shown below +> If you need other error handlers, you should place them before DotErrorhandler in the pipeline; else it will not be able to catch errors. +> We recommend using just one error handler unless you have an error-specific handler. -config/autoload/error-handling.global.php +- Configure the error handler as shown below. + +In `config/autoload/error-handling.global.php`: ```php Both `LogErrorHandler` and `ErrorHandler` have factories declared in the package's `ConfigProvider`. +> If you need a custom ErrorHandler, it must have a factory declared in the config, as in the below example: Example: ```php [ + 'dependencies' => [ 'factories' => [ - MyErrorHandler::class => MyCustomHandlerFactory::class, + \App\CustomErrorHandler::class => \App\CustomHandlerFactory::class, ], - 'aliases' => [ - ErrorHandlerInterface::class => MyErrorHandler::class, - ] + \Dot\ErrorHandler\ErrorHandlerInterface::class => \App\CustomErrorHandler::class, + ], ], 'dot-errorhandler' => [ 'loggerEnabled' => true, - 'logger' => 'dot-log.default_logger' - ] + 'logger' => 'dot-log.default_logger', + ], ]; ``` diff --git a/composer.json b/composer.json index 854cc32..5b16213 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "homepage": "https://github.com/dotkernel/dot-errorhandler", "authors": [ { - "name": "DotKernel Team", + "name": "Dotkernel Team", "email": "team@dotkernel.com" } ], @@ -26,19 +26,21 @@ } }, "require": { - "php": "~8.2.0 || ~8.3.0", - "dotkernel/dot-log": "^4.0.2", - "laminas/laminas-diactoros": "^3.3", - "laminas/laminas-stratigility": "^3.11", - "mezzio/mezzio": "^3.19", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", + "dotkernel/dot-log": "^4.0.5", + "laminas/laminas-diactoros": "^3.8.0", + "laminas/laminas-stratigility": "^4.3.0", + "mezzio/mezzio": "^3.24", "psr/http-message": "^1.0 || ^2.0", - "psr/http-server-middleware": "^1.0" + "psr/http-server-middleware": "^1.0", + "psr/log": "^3.0" }, "require-dev": { - "laminas/laminas-coding-standard": "^2.5", + "laminas/laminas-coding-standard": "^3.0", "mikey179/vfsstream": "^1.6.7", - "phpunit/phpunit": "^10.5", - "vimeo/psalm": "^5.22" + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5" }, "autoload": { "psr-4": { @@ -54,12 +56,12 @@ "scripts": { "check": [ "@cs-check", - "@test" + "@test", + "@static-analysis" ], "cs-check": "phpcs", "cs-fix": "phpcbf", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", - "static-analysis": "psalm --shepherd --stats" + "static-analysis": "phpstan analyse --memory-limit 1G", + "test": "phpunit --colors=always" } } diff --git a/config/error-handling.global.php.dist b/config/error-handling.global.php.dist index eb07019..335f7dd 100644 --- a/config/error-handling.global.php.dist +++ b/config/error-handling.global.php.dist @@ -7,10 +7,10 @@ return [ 'dependencies' => [ 'aliases' => [ ErrorHandlerInterface::class => LogErrorHandler::class, - ] + ], ], 'dot-errorhandler' => [ 'loggerEnabled' => true, - 'logger' => 'dot-log.default_logger' - ] + 'logger' => 'dot-log.default_logger', + ], ]; diff --git a/docs/book/index.md b/docs/book/index.md deleted file mode 100644 index fe84005..0000000 --- a/docs/book/index.md +++ /dev/null @@ -1 +0,0 @@ -../../README.md \ No newline at end of file diff --git a/docs/book/v3/configuration.md b/docs/book/v3/configuration.md deleted file mode 100644 index ae1f365..0000000 --- a/docs/book/v3/configuration.md +++ /dev/null @@ -1,76 +0,0 @@ -# Configuration - -Register `dot-errorhandler` in you project by adding `Dot\ErrorHandler\ConfigProvider::class` to your configuration aggregator (to `config/config.php` for example), -and add `\Dot\ErrorHandler\ErrorHandlerInterface::class` (to `config/pipeline.php` for example) **as the outermost layer of the middleware** to catch all Exceptions - -- Configure the error handler as shown below - -config/autoload/error-handling.global.php - -```php - [ - 'aliases' => [ - ErrorHandlerInterface::class => LogErrorHandler::class, - ] - - ], - 'dot-errorhandler' => [ - 'loggerEnabled' => true, - 'logger' => 'dot-log.default_logger' - ] -]; -``` - -A configuration example for the default logger can be found in `config/log.global.php.dist`. - -When declaring the `ErrorHandlerInterface` alias you can choose whether to log or not: - -- for the simple Zend Expressive handler user `ErrorHandler` -- for logging use `LogErrorHandler` - -The class `Dot\ErrorHandler\ErrorHandler` is the same as the Zend Expressive error handling class -the only difference being the removal of the `final` statement for making extension possible. - -The class `Dot\ErrorHandler\LogErrorHandler` is `Dot\ErrorHandler\ErrorHandler` with -added logging support. - -As a note: both `LogErrorHandler` and `ErrorHandler` have factories declared in the -package's `ConfigProvider`. If you need a custom ErrorHandler it must have a factory -declared in the config, as in the example. - -Example: - -```php - [ - 'factories' => [ - MyErrorHandler::class => MyCustomHandlerFactory::class, - ], - - 'aliases' => [ - ErrorHandlerInterface::class => MyErrorHandler::class, - ] - - ], - 'dot-errorhandler' => [ - 'loggerEnabled' => true, - 'logger' => 'dot-log.default_logger' - ] -]; -``` - -Config examples can be found in this project's `config` directory. diff --git a/docs/book/v3/installation.md b/docs/book/v3/installation.md deleted file mode 100644 index 723581c..0000000 --- a/docs/book/v3/installation.md +++ /dev/null @@ -1,5 +0,0 @@ -# Installation - -Install `dotkernel/dot-errorhandler` by executing the following Composer command: - - composer require dotkernel/dot-errorhandler diff --git a/docs/book/v3/overview.md b/docs/book/v3/overview.md deleted file mode 100644 index c124631..0000000 --- a/docs/book/v3/overview.md +++ /dev/null @@ -1,6 +0,0 @@ -# Overview - -`dot-errorhandler` is DotKernel's logging error handler, providing two options: - -- `Dot\ErrorHandler\ErrorHandler`, same as the Zend Expressive error handling class with the only difference being the removal of the `final` statement for making extension possible -- `Dot\ErrorHandler\LogErrorHandler` adds logging support to the default `ErrorHandler` class diff --git a/docs/book/v4/configuration.md b/docs/book/v4/configuration.md deleted file mode 100644 index ae1f365..0000000 --- a/docs/book/v4/configuration.md +++ /dev/null @@ -1,76 +0,0 @@ -# Configuration - -Register `dot-errorhandler` in you project by adding `Dot\ErrorHandler\ConfigProvider::class` to your configuration aggregator (to `config/config.php` for example), -and add `\Dot\ErrorHandler\ErrorHandlerInterface::class` (to `config/pipeline.php` for example) **as the outermost layer of the middleware** to catch all Exceptions - -- Configure the error handler as shown below - -config/autoload/error-handling.global.php - -```php - [ - 'aliases' => [ - ErrorHandlerInterface::class => LogErrorHandler::class, - ] - - ], - 'dot-errorhandler' => [ - 'loggerEnabled' => true, - 'logger' => 'dot-log.default_logger' - ] -]; -``` - -A configuration example for the default logger can be found in `config/log.global.php.dist`. - -When declaring the `ErrorHandlerInterface` alias you can choose whether to log or not: - -- for the simple Zend Expressive handler user `ErrorHandler` -- for logging use `LogErrorHandler` - -The class `Dot\ErrorHandler\ErrorHandler` is the same as the Zend Expressive error handling class -the only difference being the removal of the `final` statement for making extension possible. - -The class `Dot\ErrorHandler\LogErrorHandler` is `Dot\ErrorHandler\ErrorHandler` with -added logging support. - -As a note: both `LogErrorHandler` and `ErrorHandler` have factories declared in the -package's `ConfigProvider`. If you need a custom ErrorHandler it must have a factory -declared in the config, as in the example. - -Example: - -```php - [ - 'factories' => [ - MyErrorHandler::class => MyCustomHandlerFactory::class, - ], - - 'aliases' => [ - ErrorHandlerInterface::class => MyErrorHandler::class, - ] - - ], - 'dot-errorhandler' => [ - 'loggerEnabled' => true, - 'logger' => 'dot-log.default_logger' - ] -]; -``` - -Config examples can be found in this project's `config` directory. diff --git a/docs/book/v4/installation.md b/docs/book/v4/installation.md deleted file mode 100644 index 723581c..0000000 --- a/docs/book/v4/installation.md +++ /dev/null @@ -1,5 +0,0 @@ -# Installation - -Install `dotkernel/dot-errorhandler` by executing the following Composer command: - - composer require dotkernel/dot-errorhandler diff --git a/docs/book/v4/overview.md b/docs/book/v4/overview.md deleted file mode 100644 index c124631..0000000 --- a/docs/book/v4/overview.md +++ /dev/null @@ -1,6 +0,0 @@ -# Overview - -`dot-errorhandler` is DotKernel's logging error handler, providing two options: - -- `Dot\ErrorHandler\ErrorHandler`, same as the Zend Expressive error handling class with the only difference being the removal of the `final` statement for making extension possible -- `Dot\ErrorHandler\LogErrorHandler` adds logging support to the default `ErrorHandler` class diff --git a/mkdocs.yml b/mkdocs.yml index b95a4df..c7b60cd 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -17,7 +17,7 @@ nav: - Installation: v3/installation.md - Configuration: v3/configuration.md site_name: dot-errorhandler -site_description: "DotKernel's error logging handler" +site_description: "Dotkernel's error logging handler" repo_url: "https://github.com/dotkernel/dot-errorhandler" plugins: - search diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..349be25 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,8 @@ +includes: + - vendor/phpstan/phpstan-phpunit/extension.neon +parameters: + level: 5 + paths: + - src + - test + treatPhpDocTypesAsCertain: false diff --git a/psalm.xml b/psalm.xml deleted file mode 100644 index b4b6bb5..0000000 --- a/psalm.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - diff --git a/test/ErrorHandlerFactoryTest.php b/test/ErrorHandlerFactoryTest.php index 85676fd..01de087 100644 --- a/test/ErrorHandlerFactoryTest.php +++ b/test/ErrorHandlerFactoryTest.php @@ -45,7 +45,7 @@ public function testWillCreateWithDefaultOption(): void ->willReturn($this->responseFactory); $result = (new ErrorHandlerFactory())($this->container); - $this->assertInstanceOf(ErrorHandler::class, $result); + $this->assertContainsOnlyInstancesOf(ErrorHandler::class, [$result]); } /** @@ -57,7 +57,7 @@ public function testWillCreateWithErrorResponseGenerator(): void { $this->container->method('has') ->with(ErrorResponseGenerator::class) - ->willReturn($this->createMock(ErrorResponseGenerator::class)); + ->willReturn(true); $this->container->method('get') ->willReturnMap([ @@ -66,6 +66,6 @@ public function testWillCreateWithErrorResponseGenerator(): void ]); $result = (new ErrorHandlerFactory())($this->container); - $this->assertInstanceOf(ErrorHandler::class, $result); + $this->assertContainsOnlyInstancesOf(ErrorHandler::class, [$result]); } } diff --git a/test/ErrorHandlerTest.php b/test/ErrorHandlerTest.php index 8b9536b..c1e514e 100644 --- a/test/ErrorHandlerTest.php +++ b/test/ErrorHandlerTest.php @@ -53,7 +53,7 @@ public function setUp(): void public function testWillCreateWithDefaultParameters(): void { - $this->assertInstanceOf(Subject::class, $this->subject); + $this->assertContainsOnlyInstancesOf(Subject::class, [$this->subject]); } public function testCreateErrorHandlerReturnsCallable(): void @@ -114,7 +114,7 @@ public function testHandleThrowable(): void $response = ($this->errorResponseGenerator)($this->exception, $this->serverRequest, ($this->responseFactory)()); - $this->assertInstanceOf(ResponseInterface::class, $response); + $this->assertContainsOnlyInstancesOf(ResponseInterface::class, [$response]); } public function testErrorHandlingTriggersListeners(): void diff --git a/test/LogErrorHandlerTest.php b/test/LogErrorHandlerTest.php index 9afbb6d..317902f 100644 --- a/test/LogErrorHandlerTest.php +++ b/test/LogErrorHandlerTest.php @@ -63,7 +63,7 @@ public function setUp(): void public function testWillCreateWithDefaultParameters(): void { - $this->assertInstanceOf(Subject::class, $this->subject); + $this->assertContainsOnlyInstancesOf(Subject::class, [$this->subject]); } public function testCreateErrorHandlerReturnsCallable(): void @@ -145,7 +145,7 @@ public function testHandleThrowable(): void $response = $responseGenerator($this->exception, $this->serverRequest, ($this->responseFactory)()); - $this->assertInstanceOf(ResponseInterface::class, $response); + $this->assertContainsOnlyInstancesOf(ResponseInterface::class, [$response]); } public function testErrorHandlingTriggersListeners(): void