diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f1d8bdb..490f6fc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - New #380: Add `TagReference::id()` method (@vjik) - Enh #384: Make `$config` parameter in `Container` constructor optional (@np25071984) +- Enh #324: Make `BuildingException` friendly (@np25071984) ## 1.3.0 October 14, 2024 diff --git a/composer.json b/composer.json index 05a0abef..fdfb78a9 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,8 @@ "php": "^8.1", "ext-mbstring": "*", "psr/container": "^1.1|^2.0", - "yiisoft/definitions": "^3.0" + "yiisoft/definitions": "^3.0", + "yiisoft/friendly-exception": "^1.1.0" }, "require-dev": { "league/container": "^4.2", diff --git a/src/BuildingException.php b/src/BuildingException.php index ec410674..6d0c12cc 100644 --- a/src/BuildingException.php +++ b/src/BuildingException.php @@ -7,19 +7,20 @@ use Exception; use Psr\Container\ContainerExceptionInterface; use Throwable; +use Yiisoft\FriendlyException\FriendlyExceptionInterface; /** * It wraps all exceptions that don't implement `ContainerExceptionInterface` during the build process. * Also adds building context for more understanding. */ -final class BuildingException extends Exception implements ContainerExceptionInterface +final class BuildingException extends Exception implements ContainerExceptionInterface, FriendlyExceptionInterface { /** * @param string $id ID of the definition or name of the class that wasn't found. * @param string[] $buildStack Stack of IDs of services requested definition or class that wasn't found. */ public function __construct( - string $id, + private readonly string $id, Throwable $error, array $buildStack = [], Throwable $previous = null, @@ -32,4 +33,20 @@ public function __construct( parent::__construct($message, 0, $previous); } + + public function getName(): string + { + return sprintf('Unable to build "%s" object.', $this->id); + } + + public function getSolution(): ?string + { + $solution = <<id); + } } diff --git a/src/NotFoundException.php b/src/NotFoundException.php index a765a362..8e61400f 100644 --- a/src/NotFoundException.php +++ b/src/NotFoundException.php @@ -7,11 +7,12 @@ use Exception; use Psr\Container\NotFoundExceptionInterface; use Throwable; +use Yiisoft\FriendlyException\FriendlyExceptionInterface; /** * `NotFoundException` is thrown when no definition or class was found in the container for a given ID. */ -final class NotFoundException extends Exception implements NotFoundExceptionInterface +final class NotFoundException extends Exception implements NotFoundExceptionInterface, FriendlyExceptionInterface { /** * @param string $id ID of the definition or name of the class that was not found. @@ -49,4 +50,18 @@ public function getBuildStack(): array { return $this->buildStack; } + + public function getName(): string + { + return sprintf('No definition or class found for "%s" ID.', $this->id); + } + + public function getSolution(): ?string + { + $solution = <<id); + } } diff --git a/tests/Unit/BuildingExceptionTest.php b/tests/Unit/BuildingExceptionTest.php index 5d3e8b27..2f5c472a 100644 --- a/tests/Unit/BuildingExceptionTest.php +++ b/tests/Unit/BuildingExceptionTest.php @@ -15,6 +15,15 @@ public function testMessage(): void $exception = new BuildingException('test', new RuntimeException('i am angry')); $this->assertSame('Caught unhandled error "i am angry" while building "test".', $exception->getMessage()); + $this->assertSame('Unable to build "test" object.', $exception->getName()); + $this->assertSame( + <<getSolution() + ); } public function testEmptyMessage(): void diff --git a/tests/Unit/NotFoundExceptionTest.php b/tests/Unit/NotFoundExceptionTest.php index 0cf7266b..b7cedb72 100644 --- a/tests/Unit/NotFoundExceptionTest.php +++ b/tests/Unit/NotFoundExceptionTest.php @@ -14,6 +14,13 @@ public function testGetId(): void $exception = new NotFoundException('test'); $this->assertSame('test', $exception->getId()); + $this->assertSame('No definition or class found for "test" ID.', $exception->getName()); + $this->assertSame( + <<getSolution() + ); } public function testMessage(): void