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

[DependencyInjection] Throw better exception when missing use-statement #34239

Closed
wants to merge 2 commits into from

Conversation

Nyholm
Copy link
Member

@Nyholm Nyholm commented Nov 5, 2019

Q A
Branch? 3.4
Bug fix? yes
New feature? no
Deprecations? no
Tickets
License MIT
Doc PR

Im trying to address this issue: https://stackoverflow.com/questions/49958116/class-appbundle-controller-homecontroller-used-for-service-appbundle-controll

So here is the scenario:

namespace App\Foo;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

abstract class MyBaseController extends AbstractController{}
namespace App\Bar;

// Note that "use App\Foo\MyBaseController" is missing
use App\MyService;

class StartpageController extends MyBaseController{
    public function action(MyService $service)
    {
        // ...
    }
}

Since StartpageController is autowired and tagged with controller.service_arguments we will run it in RegisterControllerArgumentLocatorsPass.

If my cache folder is empty, I will get an error saying something like:

Class "App\Bar\StartpageController" used for service "App\Bar\StartpageController" cannot be found.

That does not make any sense.

This PR is trying to load App\Bar\StartpageController to make PHP discover that we are missing something. Now I will get a much better error:

Attempted to load class "MyBaseController" from namespace "App\Bar". Did you forget a "use" statement for "App\Foo\MyBaseController"?


If for some reason this is not the issue and PHP does not throw this error, we just continue with the normal exception.

@OskarStark
Copy link
Contributor

Class "App\Bar\StartpageController" used for service "App\Bar\StartpageController" cannot be found.

Is this really the message or is it:

- Class "App\Bar\StartpageController" used for service "App\Bar\StartpageController" cannot be found.
+ Class "App\Bar\MyBaseController" used for service "App\Bar\StartpageController" cannot be found.

@Nyholm
Copy link
Member Author

Nyholm commented Nov 6, 2019

Yes, it is really correct. I did not make a typo.

That is why the error message is confusing and a change is needed.

@nicolas-grekas
Copy link
Member

I think the attached patch is currently a hack that works around the real issue: the core issue is that getReflectionClass() caches missing classes when $throw is false. This means the return value of the function is call-order dependent.

Here is a better fix:

--- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
@@ -376,7 +376,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
             if ($throw) {
                 throw $e;
             }
-            $classReflector = false;
+            $classReflector = null;
         }
 
         if ($this->trackResources) {
@@ -392,7 +392,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
             $this->classReflectors[$class] = $classReflector;
         }
 
-        return $classReflector ?: null;
+        return $classReflector;
     }

This will display this:
image

Which is correct.

It's not as good as the one you're achieving with the class_exists(), but that's another issue: the ErrorHandler should be able to do these suggestions on ReflectionException too, not only on fatal errors. - This last part would be for 4.4.

Makes sense?

@nicolas-grekas
Copy link
Member

See #34282

@nicolas-grekas
Copy link
Member

Thanks for raising the point!

@Nyholm
Copy link
Member Author

Nyholm commented Nov 7, 2019

Thank you for improving the PR.

nicolas-grekas added a commit that referenced this pull request Nov 8, 2019
This PR was merged into the 3.4 branch.

Discussion
----------

[DI] Dont cache classes with missing parents

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Closes #34239
| License       | MIT
| Doc PR        | -

Commits
-------

1606430 [DI] Dont cache classes with missing parents
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants