diff --git a/.idea/php.xml b/.idea/php.xml
index c983c89..e97844c 100644
--- a/.idea/php.xml
+++ b/.idea/php.xml
@@ -98,6 +98,7 @@
+
diff --git a/.idea/problem-details-symfony-bundle.iml b/.idea/problem-details-symfony-bundle.iml
index 43a3eb2..a072eba 100644
--- a/.idea/problem-details-symfony-bundle.iml
+++ b/.idea/problem-details-symfony-bundle.iml
@@ -79,6 +79,7 @@
+
diff --git a/composer.json b/composer.json
index 7c62d7b..92f9e33 100644
--- a/composer.json
+++ b/composer.json
@@ -14,7 +14,8 @@
"phpmd/phpmd": "^2.5",
"phpstan/phpstan": "^2.0",
"phpunit/phpunit": "^11.5.0",
- "squizlabs/php_codesniffer": "^3.7.2"
+ "squizlabs/php_codesniffer": "^3.7.2",
+ "symfony/yaml": "^7.2"
},
"license": "MIT",
"autoload": {
diff --git a/composer.lock b/composer.lock
index 0c69640..c30d181 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "332900e0eb2d63e20627d71802900c7a",
+ "content-hash": "a5bb9a914eb4413be9ad2b40ddd478cb",
"packages": [
{
"name": "psr/event-dispatcher",
@@ -5236,6 +5236,78 @@
],
"time": "2024-10-18T07:58:17+00:00"
},
+ {
+ "name": "symfony/yaml",
+ "version": "v7.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "099581e99f557e9f16b43c5916c26380b54abb22"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/099581e99f557e9f16b43c5916c26380b54abb22",
+ "reference": "099581e99f557e9f16b43c5916c26380b54abb22",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2",
+ "symfony/deprecation-contracts": "^2.5|^3.0",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "conflict": {
+ "symfony/console": "<6.4"
+ },
+ "require-dev": {
+ "symfony/console": "^6.4|^7.0"
+ },
+ "bin": [
+ "Resources/bin/yaml-lint"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Yaml\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Loads and dumps YAML files",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/yaml/tree/v7.2.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-10-23T06:56:12+00:00"
+ },
{
"name": "theseer/tokenizer",
"version": "1.2.3",
@@ -5347,12 +5419,12 @@
],
"aliases": [],
"minimum-stability": "stable",
- "stability-flags": [],
+ "stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": "^8.2"
},
- "platform-dev": [],
+ "platform-dev": {},
"plugin-api-version": "2.6.0"
}
diff --git a/config/services.yaml b/config/services.yaml
index 4448d51..14b47a6 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -12,21 +12,21 @@ services:
arguments:
$validationErrorsBuilder: '@Phauthentic\Symfony\ProblemDetails\Validation\ValidationErrorsBuilder'
$problemDetailsResponseFactory: '@Phauthentic\Symfony\ProblemDetails\FromExceptionEventFactoryInterface'
- tags:
- - { name: 'phauthentic.problem_details.exception_converter' }
+ tags: ['phauthentic.problem_details.exception_converter']
Phauthentic\Symfony\ProblemDetails\ExceptionConversion\HttpExceptionConverter:
arguments:
$problemDetailsFactory: '@Phauthentic\Symfony\ProblemDetails\ProblemDetailsFactoryInterface'
- tags:
- - { name: 'phauthentic.problem_details.exception_converter' }
+ tags: ['phauthentic.problem_details.exception_converter']
Phauthentic\Symfony\ProblemDetails\ExceptionConversion\GenericExceptionConverter:
- tags:
- - { name: 'phauthentic.problem_details.exception_converter' }
+ arguments:
+ $problemDetailsFactory: '@Phauthentic\Symfony\ProblemDetails\ProblemDetailsFactoryInterface'
+ tags: ['phauthentic.problem_details.exception_converter']
Phauthentic\Symfony\ProblemDetails\ThrowableToProblemDetailsKernelListener:
+ public: true
arguments:
$exceptionConverters: !tagged_iterator phauthentic.problem_details.exception_converter
tags:
- - { name: 'kernel.event_listener', event: 'kernel.exception', priority: 0 }
\ No newline at end of file
+ - { name: 'kernel.event_listener', event: 'kernel.exception', priority: 0 }
diff --git a/readme.md b/readme.md
index baa4437..70ed65f 100644
--- a/readme.md
+++ b/readme.md
@@ -12,7 +12,9 @@ This bundle provides support for [RFC 9457](https://www.rfc-editor.org/rfc/rfc94
composer require phauthentic/problem-details-symfony-bundle
```
-## Docs
+## Documentation
+
+Simply inject the `ProblemDetailsFactoryInterface` into your handlers and use it to create `ProblemDetails` responses.
```php
class ExampleController
@@ -37,6 +39,31 @@ class ExampleController
}
```
+### Service Configuration
+
+To add more converters to the kernel listener, you can tag additional services with `phauthentic.problem_details.exception_converter`. They must implement the [ExceptionConverterInterface](src/ExceptionConversion/ExceptionConverterInterface.php).
+
+```yaml
+ Phauthentic\Symfony\ProblemDetails\ExceptionConversion\ValidationFailedExceptionConverter:
+ arguments:
+ $validationErrorsBuilder: '@Phauthentic\Symfony\ProblemDetails\Validation\ValidationErrorsBuilder'
+ $problemDetailsResponseFactory: '@Phauthentic\Symfony\ProblemDetails\FromExceptionEventFactoryInterface'
+ tags: ['phauthentic.problem_details.exception_converter']
+```
+
+To completely override the list of already configured listeners override
+
+```yaml
+ Phauthentic\Symfony\ProblemDetails\ThrowableToProblemDetailsKernelListener:
+ public: true
+ arguments:
+ $exceptionConverters: !tagged_iterator phauthentic.problem_details.exception_converter
+ tags:
+ - { name: 'kernel.event_listener', event: 'kernel.exception', priority: 0 }
+```
+
+in your `services.yaml`.
+
## Problem Details Example
```text
diff --git a/src/ExceptionConversion/GenericExceptionConverter.php b/src/ExceptionConversion/GenericExceptionConverter.php
index 6c4bb8d..d259a3e 100644
--- a/src/ExceptionConversion/GenericExceptionConverter.php
+++ b/src/ExceptionConversion/GenericExceptionConverter.php
@@ -15,13 +15,6 @@
* Notice that you might need to adjust the priority of the listener in your services.yaml file to make sure it is
* executed in the right order if you have other listeners.
*
- *
- * Phauthentic\Symfony\ProblemDetails\ThrowableToProblemDetailsKernelListener:
- * arguments: ['%kernel.environment%', { }]
- * tags:
- * - { name: kernel.event_listener, event: kernel.exception, priority: -20 }
- *
- *
* @link https://www.rfc-editor.org/rfc/rfc9457.html
*/
class GenericExceptionConverter implements ExceptionConverterInterface
diff --git a/tests/Unit/ExceptionConversion/GenericThrowableConverterTest.php b/tests/Unit/ExceptionConversion/GenericExceptionConverterTest.php
similarity index 97%
rename from tests/Unit/ExceptionConversion/GenericThrowableConverterTest.php
rename to tests/Unit/ExceptionConversion/GenericExceptionConverterTest.php
index ea19946..6802f65 100644
--- a/tests/Unit/ExceptionConversion/GenericThrowableConverterTest.php
+++ b/tests/Unit/ExceptionConversion/GenericExceptionConverterTest.php
@@ -18,7 +18,7 @@
/**
*
*/
-class GenericThrowableConverterTest extends TestCase
+class GenericExceptionConverterTest extends TestCase
{
public function setUp(): void
{
diff --git a/tests/Unit/ServiceLoadingTest.php b/tests/Unit/ServiceLoadingTest.php
new file mode 100644
index 0000000..187d00a
--- /dev/null
+++ b/tests/Unit/ServiceLoadingTest.php
@@ -0,0 +1,47 @@
+load('services.yaml');
+ $container->compile();
+
+ // Assert
+ $listener = $container->get(ThrowableToProblemDetailsKernelListener::class);
+ $this->assertInstanceOf(ThrowableToProblemDetailsKernelListener::class, $listener);
+
+ $reflectionClass = new ReflectionClass($listener);
+ $converters = $reflectionClass->getProperty('exceptionConverters')->getValue($listener);
+ $result = [];
+ foreach ($converters as $converter) {
+ $result[] = get_class($converter);
+ }
+ $this->assertCount(3, $result);
+ $this->assertEquals([
+ ValidationFailedExceptionConverter::class,
+ HttpExceptionConverter::class,
+ GenericExceptionConverter::class,
+ ], $result);
+ }
+}