Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolving middleware breaks if resolver throws unexpected exception type #3071

Open
Rarst opened this issue Apr 21, 2021 · 4 comments
Open

Comments

@Rarst
Copy link
Contributor

Rarst commented Apr 21, 2021

CallableResolver call is wrapped in a catch that expects RuntimeException

if ($this->callableResolver instanceof CallableResolverInterface) {
try {
$callable = $this->callableResolver->resolve($this->middleware);
} catch (RuntimeException $e) {
// Do Nothing
}
}
if (!$callable) {

If a resolver throws exception that doesn't extend from RuntimeException this halts the execution and fallback code below is never reached.

Real example of the issue with third party resolver: PHP-DI/Slim-Bridge#51

I am not sure what's the reasoning for specifically RuntimeException here, but broadening it to Exception might be a good idea for resilience?

@dakujem
Copy link

dakujem commented Apr 21, 2021

I'm not sure if silencing all exceptions thrown by callable resolver is the best idea, personally.

Having a dedicated interface for this would be better, but it would also introduce a possible breaking change for callable resolver implementors.

something like this:

if ($this->callableResolver instanceof CallableResolverInterface) { 
     try { 
         $callable = $this->callableResolver->resolve($this->middleware); 
     } catch (UnableToResolveCallableExceptionInterface $e) { 
         // Do Nothing 
     } 
 } 

A better interface name is needed.

@Rarst
Copy link
Contributor Author

Rarst commented Apr 21, 2021

@dakujem note that there is already AdvancedCallableResolverInterface, I am guessing CallableResolverInterface is retained for backwards compatibility so breaking changes to it are probably not an option.

@l0gicgate
Copy link
Member

l0gicgate commented Apr 25, 2021

@Rarst

I am guessing CallableResolverInterface is retained for backwards compatibility so breaking changes to it are probably not an option.

This is exactly why. Ultimately in Slim 5 we should get rid of AdvancedCallableResolver and unify the 2.

AdvancedCallableResolver came in after the initial release of Slim 4 at which point we couldn't make changes to CallableResolver without breaking things.

This is unfortunately technical debt that needs to be resolved in Slim 5.

I am not sure what's the reasoning for specifically RuntimeException here, but broadening it to Exception might be a good idea for resilience?

I don't think that this is correct. We need to specifically ensure that the exception thrown is because the callable could not be resolved and not do a catch-all because we have no idea what's happening downstream.

We will need a named exception like CannotResolveCallableException or something like that.

@Rarst
Copy link
Contributor Author

Rarst commented Apr 26, 2021

We need to specifically ensure that the exception thrown is because the callable could not be resolved

I follow the sentiment. The current implementation neither ensures that distinction or lets fallback code be consistently reached.

My initial thought was to prioritize reaching fallback code since that would make more cases work.

Making more cases fail clearly does not look possible without introducing a new exception and having to rewrite existing interface implementers. At which point they could as well update to advanced interface.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants