--
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+unsubscribe@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/CAJp_myU%2BwCPNbmhdMGztNvzmgrjpO-giGBE8fuuJT4Lj%3DDVVGg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
LGTM from PEAR...
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/CAJp_myU%2BwCPNbmhdMGztNvzmgrjpO-giGBE8fuuJT4Lj%3DDVVGg%40mail.gmail.com.
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+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/CANsgjnuVHjWScCCkuuf5LkT7OHXZAa%3DmvyvRVMB4sC%3DXLOhcVA%40mail.gmail.com.
--
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+unsubscribe@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/a77b3d96-2edf-e5ad-4cc1-d41ffaa9a9b1%40garfieldtech.com.
the NotFoundExceptionInterface triggered by the inner get call SHOULD NOT bubble out.
"Don't standardize an *exception interface* for a known error case because *nobody* can think of a reason you'd catch that"
- It is useful for routers to fetch a controller from the container.
- It is useful for writing adapters extending any containers.
- It is useful for composing containers.
- It is useful for writing factories that do not depend on a particular container.
Also, I'd like to make a parallel with PSR-7 and PSR-15. PSR-7 is already useful by itself, but it will be immensely more useful when PSR-15 passes. It is the same with PSR-11. It will be the cornerstone of interoperable service providers. As soon as PSR-11 passes, we plan forming a working group on standardizing service providers (see https://github.com/container-interop/service-provider/ for more details). PSR-11 is a prerequisite.
What "id" should the router "get()"?
Without ContainerInterface, I should have used an Adapter (e.g. the Acclimate package) or I could have hardwired a specific container into my framework to achieve so (I would have hated both solutions).
That basically means a simple closure would do the job equally well, isn't?
...
...
> > 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.
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 and Matthew pointed a few things that were never said before.
Namely:
NotFoundExceptionInterface
duplicates the concept of the has
method (in Nicolas post)Based on these 2 assertions (I agree with both), we should question the usefulness of NotFoundExceptionInterface
as it is defined today.
We spent a lot of time to make sure that containers implementing PSR-11 are differentiating the NotFoundExceptionInterface
from a "missing dependency exception" (that should exist in the
container even if it is not standardized). This involves that
implementing containers MUST catch the NotFoundExceptionInterface
and rethrow another exception. So we are forcing an "implementation detail" into implementors.
And I've come to realize that contrary to what I believed, we absolutely don't need that.
The change I'm proposing is dead simple: let's drop any distinction between "entry not found" and "dependency missing". We don't need this because users of containers can anyway figure that out.
If a user of a container wants to make the distinction between "not
found" and "missing dependency", he can simply perform a call to has
before calling get
:
if (!$container->has($id)) { // The requested instance does not exist // Let's do some stuff like display an error message return; } try { $entry = $container->get($id); } catch (NotFoundExceptionInterface $e) { // Since the requested entry DOES exist, a NotFoundExceptionInterface means that a dependency is missing! }
Advantages:
NotFoundExceptionInterface
must not bubble up (no forced catch and rethrow, which feeled a bit flacky)NotFoundExceptionInterface
bubble upNotFoundExceptionInterface
and wrap it in a "MissingDependencyException" of their own that must itself implement the NotFoundExceptionInterface
Inconvenient:
NotFoundExceptionInterface
(this is actually not clearly stated in the container-interop documentation)The more I think about it, the more I'm seduced by this solution. It
is simple, it leaves complete freedom to implementors, and container
users can still figure out if the exception they get is a "not found" or
a "missing dependency" with a simple has
call.
It also enforces best practices as users that want to check if an entry exists will use has
instead of NotFoundExceptionInterface
(the exception can no more be used for control flow)
Note: I haven't had a chance to speak with Matthieu, the other editor, about it yet since deadlines are tight, I'm sharing it right now. Matthieu, if you think this is foolish, we can cancel that.
As you can see, the PR makes PSR-11 even more simple, which is generally a good sign: https://github.com/php-fig/fig-standards/pull/869
What do you guys think?
++
David.
let's drop any distinction between "entry not found" and "dependency missing". We don't need this because users of containers can anyway figure that out.
NotFoundExceptionInterface
] duplicate the "has()"
method?"NotFoundExceptionInterface
and define it a to be thrown by "get" only and only if would have returned false.NotFoundExceptionInterface
whenever "has" would have returned false - it "directly" throws ContainerExceptionInterface
- and is allowed to let anything else bubble if thrown by the factories/initializers it calls.It also enforces best practices as users that want to check if an entry exists will usehas
instead ofNotFoundExceptionInterface
(the exception can no more be used for control flow)
NotFoundExceptionInterface
could be used for flow control. But since doing so would be strictly equivalent to call "has", we could even add in the PSR a SHOULD NOT - if worth it.--
You received this message because you are subscribed to a topic in the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/php-fig/I1a2Xzv9wN8/unsubscribe.
To unsubscribe from this group and all its topics, 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/CAOWwgpmQZnbvCfLkE58mDhBT3NHCWqdkPabPEsJRkezTHZm-AQ%40mail.gmail.com.
Regarding you last suggestion I'm having trouble seeing the difference with the current version of the spec, could you pinpoint it more explicitly?
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
.NotFoundExceptionInterface
, then it's a second level missing dep. Isn't it?The second one is a really technical consequence I didn't realize when writing the previous comment:It makes this statements useless (which is a good thing since that's the one we're worried about):
> A call toget
can trigger additional calls toget
(to fetch the dependencies). If one of those dependencies is missing, theNotFoundExceptionInterface
triggered by the innerget
call SHOULD NOT bubble out. Instead, it should be wrapped in an exception implementing theContainerExceptionInterface
that does not implement theNotFoundExceptionInterface
.If one wants to be able to really differentiate these situations, one can already do:just check "has" before "get". If, after doing so, "get" throws aNotFoundExceptionInterface
, then it's a second level missing dep. Isn't it?
--You received this message because you are subscribed to a topic in the Google Groups "PHP Framework Interoperability Group" group.To unsubscribe from this topic, visit https://groups.google.com/d/topic/php-fig/I1a2Xzv9wN8/unsubscribe.To unsubscribe from this group and all its topics, 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/398f3c10-6e15-4248-ae89-2193968cffa7%40googlegroups.com.For more options, visit https://groups.google.com/d/optout.
Ok, we have 3 options, and one day to decide which to choose.
In order to ease the choice, I opened 3 PRs on Github.
I'll ask everyone involved to give feedback on the 3 PRs.
Let me present them briefly.
PR 1: Status Quo: NotFoundExceptionInterface CANNOT bubble up, but we do not standardize MissingDependencyException
Link: https://github.com/php-fig/fig-standards/pull/870/files
This PR simply improves the current wording. It is easier to understand but is strictly equivalent to PSR-11 as it is today.
PR 2: NotFoundExceptionInterface CAN bubble up
Link: https://github.com/php-fig/fig-standards/pull/869/files
This PR let's NotFoundExceptionInterface bubble up. So a `NotFoundExceptionInterface` means either "entry not found" OR "missing dependency". The user can make the difference between the 2 using the `has` method.
PR 3: NotFoundExceptionInterface CANNOT bubble up, but we add a MissingDependencyException
Link: https://github.com/php-fig/fig-standards/pull/871/files
This PR adds an explicit MissingDependencyExceptionInterface.
Could I ask each of you to have a brief look at these PR and to tell us how you like those?
Also, for the voting member, please indicate if one of these PRs would change your vote from -1 to +1 (or the other way around)
--
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+unsubscribe@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/398f3c10-6e15-4248-ae89-2193968cffa7%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Unsurprisingly I'd favor PR 3: Explicit exception.I'll be honest that I'm still very confused why there's so much resistance from the Editors on using exception types for what they're supposed to be used for. Different error condition, different exception. In 20 years of writing code I cannot recall ever saying "damn, this error message is too precise and specific". I have said the opposite more times than I can count.
PR 1 would resolve the awkward wording, although I do feel it is the inferior approach as it is less precise and provides less contextual information for callers. (That we don't at the moment know when a caller would want that extra information is, IMO, irrelevant as it's so easy to provide.)PR 2 actively works to make using the spec harder, and I cannot get behind that at all.I am admittedly unlikely to vote +1 on the spec regardless, but should it pass anyway I feel it should still be as good (or least bad) as possible, and that is PR 3.
Larry,
Unsurprisingly I'd favor PR 3: Explicit exception.
I'll be honest that I'm still very confused why there's so much resistance from the Editors on using exception types for what they're supposed to be used for. Different error condition, different exception. In 20 years of writing code I cannot recall ever saying "damn, this error message is too precise and specific". I have said the opposite more times than I can count.
David works on his personal time to implement something that you want, we both say that we are ready to accept that change if you think this is mandatory for you to accept the spec, I don't see how you can call that "resistance" but maybe that's just a wording issue and I shouldn't take too much notice of that.
Also I just want to point out that of course there should be very precise and explicit exceptions, we all agree on that. It's just that we don't believe the interface (as such, the spec) makes sense because you wouldn't need to catch it. Implementors *should* make very explicit exceptions. Anyway, again this is just my opinion and I understand you may not share it, I just want to make sure we are talking about the same thing.
PR 1 would resolve the awkward wording, although I do feel it is the inferior approach as it is less precise and provides less contextual information for callers. (That we don't at the moment know when a caller would want that extra information is, IMO, irrelevant as it's so easy to provide.)
PR 2 actively works to make using the spec harder, and I cannot get behind that at all.
I am admittedly unlikely to vote +1 on the spec regardless, but should it pass anyway I feel it should still be as good (or least bad) as possible, and that is PR 3.
If I understand correctly you might vote -1 because:
> That is, with that [the dependency lookup feature] removed, what's left to standardize? get() and has() are barely an specification.
What do you think of the fact that some frameworks (Slim, Zend Expressive, Silly…) or some libraries (Behat…) are able to integrate with any container thanks to ContainerInterface? Do you disagree it justifies the existence of PSR-11?
--
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/6a519848-a45b-401e-a111-92c79cdb0860%40googlegroups.com.
public function get($id){ if (!isset($this->services[$id])) { throw new NotFoundServiceException($id); }
return $this->getService($id);}
private function getService(){ // This method may recursively call itself // And this method never throws NotFoundServiceException}
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.
> 31st December: Latest date for any PSRs to start approval votes under the old system> 31st December: Final deadline for PSRs to have full working groups formed with a CC sponsor> 1st January: All votes and actions take place under new system; full transition> 31st January: Deadline for any PSRs which entered review before the 17th December to form a Working Group with a CC sponsor if they failed their approval vote/didn’t get to their approval vote in timeWhere's a 17th deadline for January? In general, I don't think rushing specifications because of a strict dead line is a good thing.