From 5f0037b2e93d6f8740d55dc2106bd7e303e3f14f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Sat, 14 Jan 2017 23:30:30 +0100 Subject: [PATCH 1/3] Reworking NotFoundExceptionInterface purpose --- proposed/container.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/proposed/container.md b/proposed/container.md index aa25c7ef3..eb758d1d0 100644 --- a/proposed/container.md +++ b/proposed/container.md @@ -38,8 +38,7 @@ An entry identifier is any PHP-legal string of at least one character that uniqu - `has` takes one unique parameter: an entry identifier, which MUST be a string. `has` MUST return `true` if an entry identifier is known to the container and `false` if it is not. - `has($id)` returning true does not mean that `get($id)` will not throw an exception. - It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`. + If `has($id)` returns false, `get($id)` MUST throw a `NotFoundExceptionInterface`. ### 1.2 Exceptions @@ -49,12 +48,6 @@ Exceptions directly thrown by the container SHOULD implement the A call to the `get` method with a non-existing id MUST throw a [`Psr\Container\NotFoundExceptionInterface`](#not-found-exception). -A call to `get` can trigger additional calls to `get` (to fetch the dependencies). -If one of those dependencies is missing, the `NotFoundExceptionInterface` triggered by the -inner `get` call SHOULD NOT bubble out. Instead, it should be wrapped in an exception -implementing the `ContainerExceptionInterface` that does not implement the -`NotFoundExceptionInterface`. - ### 1.3 Recommended usage Users SHOULD NOT pass a container into an object so that the object can retrieve *its own dependencies*. From 3b0d2bf45bf798fdb8364bc9fb7a063a68d6b3e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 16 Jan 2017 18:29:20 +0100 Subject: [PATCH 2/3] Adapting META document to reworked NotFoundExceptionInterface definition --- proposed/container-meta.md | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/proposed/container-meta.md b/proposed/container-meta.md index f4708cb9c..adc062e8c 100644 --- a/proposed/container-meta.md +++ b/proposed/container-meta.md @@ -275,38 +275,32 @@ However, most PHP-FIG members considered it to be a best practice. Base exceptio A call to the `get` method with a non-existing id must throw an exception implementing the `Psr\Container\NotFoundExceptionInterface`. -There is a strong relationship with the behaviour of the `has` method. - For a given identifier: - if the `has` method returns `false`, then the `get` method MUST throw a `Psr\Container\NotFoundExceptionInterface`. -- if the `has` method returns `true`, then the `get` method MUST NOT throw a `Psr\Container\NotFoundExceptionInterface`. However, this does not mean that the `get` method will succeed and throw no exception. +- if the `has` method returns `true`, this does not mean that the `get` method will succeed and throw no exception. It can even throw a `Psr\Container\NotFoundExceptionInterface` if one of the dependencies of the requested entry is missing. + +Therefore, when a user catches the `Psr\Container\NotFoundExceptionInterface`, it has 2 possibles meanings [[9]](#link_not_found_behaviour): -When discussing the `ǸotFoundException`, a question arose to know whether the `NotFoundExceptionInterface` should have a `getMissingIdentifier()` method allowing the user catching the exception to know which identifier was not found. -Indeed, a `ǸotFoundExceptionInterface` may have been triggered by a call to `get` in one of the dependencies, which is different from a call to `get` on a non existing identifier. +- the requested entry does not exist (bad request) +- or a dependency of the requested entry does not exist (i.e. the container is misconfigured) -After some discussion [[9]](#link_not_found_behaviour), it was decided that the `getIdentifier` method was not needed. Instead, it is important to stress out that the `get` method of the container SHOULD NOT throw a `NotFoundExceptionInterface` in case of a missing dependency. Instead, the container is expected to wrap the `NotFoundExceptionInterface` into another exception simply implementing the `ContainerExceptionInterface`. +The user can however easily make a distinction with a call to `has`. -In pseudo-code, a correct implementation of `get` should look like this: +In pseudo-code: ```php -public function get($identifier) { - if (identifier not found) { - throw NotFoundException::entryNotFound($identifier); - } - try { - // Do instantiation work - // Note: this instantiation work triggers additional calls to `get` for dependencies - // Returns the entry - } catch (NotFoundExceptionInterface $e) { - // Wrap the NotFoundExceptionInterface into another exception that does not implement the `NotFoundExceptionInterface`. - throw new MissingDependencyException('some text', 0, $e); - } +if (!$container->has($id)) { + // The requested instance does not exist + return; +} +try { + $entry = $container->get($id); +} catch (NotFoundExceptionInterface $e) { + // Since the requested entry DOES exist, a NotFoundExceptionInterface means that the container is misconfigured and a dependency is missing. } ``` -With this rule in place, a user of a container can safely know that a `NotFoundExceptionInterface` means the identifier he provided to the `get` method is missing, and not that some dependency is missing. - 8. Implementations ------------------ @@ -391,5 +385,5 @@ Are listed here all people that contributed in the discussions or votes (on cont 1. [Statistical analysis of existing containers method names](https://gist.github.com/mnapoli/6159681) 1. [Discussion about the method names and parameters](https://github.com/container-interop/container-interop/issues/6) 1. [Discussion about the usefulness of the base exception](https://groups.google.com/forum/#!topic/php-fig/_vdn5nLuPBI) -1. [Discussion about the `NotFoundExceptionInterface` structure](https://github.com/container-interop/container-interop/issues/37) +1. [Discussion about the `NotFoundExceptionInterface`](https://groups.google.com/forum/#!topic/php-fig/I1a2Xzv9wN8) 1. Discussion about get optional parameters [in container-interop](https://github.com/container-interop/container-interop/issues/6) and on the [PHP-FIG mailing list](https://groups.google.com/forum/#!topic/php-fig/zY6FAG4-oz8) From 69b98dd134ed4802c1ea303c5478546e9e0f10fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 16 Jan 2017 19:03:03 +0100 Subject: [PATCH 3/3] Fixing typo --- proposed/container-meta.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposed/container-meta.md b/proposed/container-meta.md index adc062e8c..0d14ca750 100644 --- a/proposed/container-meta.md +++ b/proposed/container-meta.md @@ -280,7 +280,7 @@ For a given identifier: - if the `has` method returns `false`, then the `get` method MUST throw a `Psr\Container\NotFoundExceptionInterface`. - if the `has` method returns `true`, this does not mean that the `get` method will succeed and throw no exception. It can even throw a `Psr\Container\NotFoundExceptionInterface` if one of the dependencies of the requested entry is missing. -Therefore, when a user catches the `Psr\Container\NotFoundExceptionInterface`, it has 2 possibles meanings [[9]](#link_not_found_behaviour): +Therefore, when a user catches the `Psr\Container\NotFoundExceptionInterface`, it has 2 possible meanings [[9]](#link_not_found_behaviour): - the requested entry does not exist (bad request) - or a dependency of the requested entry does not exist (i.e. the container is misconfigured)