I'll try an analogy with Java.

In Java, there is a difference between checked and unchecked exceptions. 
Checked exceptions are the exceptions that should be catched by the user. 
Unchecked exceptions are the exceptions for which it makes no sense to 
catch them. There is no reason to catch an "unchecked exception" because 
there is no way the user can provide an interesting alternative behaviour 
in the catch statement. So unchecked exception should essentially always 
bubble up all the way to the top of the application and trigger an 
exception middleware.

For PSR-11, we deemed that the NotFoundExceptionInterface was a checked 
exception (because if the container does not contain the entry you are 
looking for, the user can maybe try an alternative behaviour like looking 
for an alias or creating a default entry).
We also deemed that the DependencyNotFoundExceptionInterface was an 
unchecked exception (because it means the container is poorly configured 
and there is little to do about it except display an error message).

Finally, we think that checked exceptions should be part of a PSR while 
unchecked exceptions should be out of any PSR (because there is no need to 
standardize an exception if you don't need to catch it).

Of course, there is no absolute truth here. We could decide that the 
NotFoundExceptionInterface should be "unchecked" (because you can always 
call "has" before "get" so there is no reason this exception should be 
catched). Also, since it boils down to "what valid use case can I have to 
catch a DependencyNotFoundExceptionInterface?", we could also find a valid 
use case for catching DependencyNotFoundExceptionInterface and decide it 
should be part of the PSR. But so far, a quick survey of frameworks out 
there has shown that no-one ever catches the "dependency not found 
exceptions".

Also, Larry, you say:









*... based on the spec alone (no metadoc, no GitHub threads) the following 
would be legal: try {   $c1->get('a'); } catch (NotFoundExceptionInterface 
$e) {   print $e->getMessage();   // prints "Service 'b' not found" }*
This is not completely true. The spec states that:


*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.*
So your code example is only valid if the container decides not to follow 
the recommendation (we used "SHOULD NOT" instead of "MUST NOT" to cope with 
existing containers). Of course, we could also strengthen the wording and 
write: *If one of those dependencies is missing, the 
NotFoundExceptionInterface triggered by the inner get call MUST NOT bubble 
out.*
This way, your code sample would be illegal (but it would be harder for 
existing containers to implement PSR-11). I have no strong opinion about 
the "SHOULD NOT" vs "MUST NOT" idea so far. Your comments are welcome.

++
David.


Le jeudi 3 novembre 2016 19:54:15 UTC+1, Daniel Plainview a écrit :
>
> > but because it doesn't know that it's a child it just throws "I don't 
> have it", which gets thrown all the way up to the initial caller, who goes 
> "wait, wat?"
>
> It would be considered as bugged PSR-11 implementation. 
>
> > then it needs to wrap that inner Not-Found with... something.  That 
> something should be standardized.
>
> Why?
>
> On Thursday, November 3, 2016 at 6:32:15 PM UTC+3, Larry Garfield wrote:
>>
>> From moufmouf in that thread:
>>
>> " The logic behind this is that if a user is calling the get method on 
>> 'foo' and 'foo' does not exist, it is very different from the user 
>> calling get on 'foo' and the 'foo' service has a missing dependency. In one 
>> case, maybe the user screwed up something (i.e. checked exception), in the 
>> other case, it is the container configuration that is screwed up 
>> (i.e. unchecked exception)."
>>
>> They are different error cases.  Different error cases should be 
>> different exceptions.  If not, then based on the spec alone (no metadoc, no 
>> GitHub threads) the following would be legal:
>>
>> try {
>>   $c1->get('a');
>> } catch (NotFoundExceptionInterface $e) {
>>   print $e->getMessage();
>>   // prints "Service 'b' not found"
>> }
>>
>> Because a delegated container didn't have a particular dependency, but 
>> because it doesn't know that it's a child it just throws "I don't have it", 
>> which gets thrown all the way up to the initial caller, who goes "wait, 
>> wat?"  If the parent container is going to catch it and handle it, then it 
>> needs to wrap that inner Not-Found with... something.  That something 
>> should be standardized.
>>
>> If I as the caller don't care which type of exception is thrown, well, 
>> that's where interfaces that cover both exceptions are helpful. :-)
>>
>> --Larry Garfield
>>
>> On 11/03/2016 03:53 AM, David Négrier wrote:
>>
>> @Larry: the DependencyNotFoundException was discussed quite recently.
>>
>> Here is the relevant link explaining the story behind it and why there is 
>> no DependencyNotFoundException: 
>> https://github.com/php-fig/fig-standards/pull/810
>>
>>
>> Le mercredi 2 novembre 2016 22:53:13 UTC+1, Matthieu Napoli a écrit : 
>>>
>>> Splitting off the main review thread, quoting Larry: 
>>>
>>> > 1) What other exceptions might get($id) throw besides 
>>> NotFoundException? 
>>>
>>> \Exception (because any exception could be thrown when creating 
>>> services) => are you suggesting we should document it in the standard?
>>>
>>> > 2) I would much prefer to see a DependencyNotFoundException defined 
>>> for 
>>> that case than leaving that up to individual implementers. Standard 
>>> error handling is just as important if not moreso than the happy path.  
>>>
>>> Why/when would one want to catch that exception (use case)? This is not 
>>> a need we have seen when using container-interop as of now, I'm of course 
>>> not against adding new stuff but we should do it for a reason.
>>>
>>> Matthieu
>>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "PHP Framework Interoperability Group" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to php-fig+u...@googlegroups.com.
>> To post to this group, send email to php...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/php-fig/c341150d-2834-42ba-a7ac-058510f4cb7c%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/php-fig/c341150d-2834-42ba-a7ac-058510f4cb7c%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups "PHP 
Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to php-fig+unsubscr...@googlegroups.com.
To post to this group, send email to php-fig@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/php-fig/79211317-71e6-4763-92e0-328d292e9484%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to