> > > the NotFoundExceptionInterface triggered by the inner get call SHOULD 
> NOT bubble out. 
> > 
> > Fortunately enough, this is only a "SHOULD NOT", so we can do as we want 
> and still be compliant. Because I agree with Larry here, the wording is so 
> abstract that in practice it hardly helps. What does missing mean? Eg does 
> a brokenly configured first level service qualify as such? 
> > Reasoning from the inside of the container, you may say no. 
> > But reasoning from the outside, the user might expect a yes, so that eg 
> a chained-container can continue with the next container in the chain 
> (provided NotFoundExceptionInterface VS ContainerExceptionInterface could 
> be the trigger to decide if the chain should break or continue? what is it 
> for otherwise? doesn't that concept duplicate the "has()" method?) 
>
> This sounds like using exceptions for control flow, which is often a 
> questionable design choice. 
>
> I agree with Nicolas here, however, in that I'd likely allow the 
> NotFoundExceptionInterface to bubble out in this case, not for control 
> flow, but 
> to make it clear to the end user that a dependency is missing from the 
> container. 
>


Ok, let me just explain how we decided to handle exceptions this way. This 
might help the debate here.

*Our first idea was that the NotFoundExceptionInterface should have a 
`getMissingIdentifier()` method.*

Let's pretend you are using a PSR-11 container. In my case, I was building 
a UI that was letting you explore a container. The user types an entry 
name, the UI displays informations about the returned service.

If I catch a NotFoundExceptionInterface, it has a very different meaning if 
the NotFoundException is thrown by my first `get` call or an inner get 
call. In one case, the user typed a buggy entry name, in the other case, 
the container is misconfigured.

So my code was looking like this:

try {
    $service = $container->get($id);
} catch (NotFoundExceptionInterface $e) {
    if ($id === $e->getMissingIdentifier()) {
        // Display an error message to the user saying the service does not 
exist
    } else {
        // Oops, I should not have caught that in the first place, I don't 
know what to do with this, let's rethrow this.
        throw $e;
    }
}

When someone catches the "NotFoundException", the "if" statement inside the 
"catch" was almost systematic.

This is because we actually have 2 different exceptions. One is "the user 
provided an invalid identifier", and the other is: "the container 
configuration somewhere has an error, with probably an invalid identifier 
stored".

So we decided that those 2 exception cases should be treated differently.

By restricting the scope of the NotFoundExceptionInterface to the first 
outermost `get` call, one user can write:

try {
    $service = $container->get($id);
} catch (NotFoundExceptionInterface $e) {
    // Display an error message to the user saying the service does not 
exist
    // No need to bother checking that the caught exceptions relate to $id, 
this is sure.
}

Now, I understand this can be discussed in many ways.

For instance, one could argue that my example is buggy, because I'm using 
exceptions for control flow. If I'm dealing with user input, I should first 
use "has" (and therefore, I'm sure the entry does exist, so if a 
"XxxNotFoundException" is triggered, it has to be a "missing dependency 
exception".

I don't think there is "one and only one" truth regarding the definition of 
exceptions. It really depends on where one puts the cursor, and the FIG has 
never defined clearly which exceptions should be part of a PSR and which 
should be out of it.

@Nicolas, @Mwop, if you think the exception handling of PSR-11 can be 
improved, could you describe precisely what you would change, why and how? 
Is this a wording issue or is this a design issue? Also, is this completely 
blocking you from implementing PSR-11? And is this a subject that could 
change a -1 to a +1 vote (that question is for Fabien and Larry :) )

As you might guess, I'm pretty happy with the exceptions the way they are 
defined currently.

Yet, I'm really happy to discuss this issue if you think it is worthwhile, 
but we have a strong deadline. If we change the way exceptions are handled, 
we must do so before Tuesday, 17th because it is the last possible date for 
a PSR to enter (again) a review phase, so please, give me your comments as 
quickly as possible.

++
David.

-- 
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/39878c6b-d9ce-4db3-ae1d-85e4ce1db73e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to