-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Debug] [WIP] Developer friendly Class Not Found and Undefined Function errors. #8156
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
Conversation
@@ -40,6 +42,11 @@ class ErrorHandler | |||
E_PARSE => 'Parse', | |||
); | |||
|
|||
private $classNameToUseStatementSuggestions = array( | |||
'Request' => 'Symfony\Component\HttpFoundation\Request', | |||
'Response' => 'Symfony\Component\HttpFoundation\Response', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This map is totally arbitrary. Why would you include these classes and not others ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea proposed was to have some "common cases" accounted for. Things like Request
and Response
are easy to forget if you're building a new controller. There were a few other ideas that would have been far more heavy handed:
- Build a static class map for all of the Symfony components that might be installed
- Do some analysis/poll for classes that people frequently forget to
use
and just expand a smaller curated list - Dynamically build out a class map at runtime based on the current autoloader rules
I prefer the latter but it would be a lot of work so I started out with a simple map to get the conversation started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think @schmittjoh did some analysis as part of JMSDebugging
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or, similar to the usage of get_defined_functions
, what about using get_declared_classes
, get_declared_interfaces
, and get_declared_traits
? It might still need one of your three semi-static common case ideas since Request
and Response
aren't necessarily loaded by the time an error shows up.
Also, thanks for your work - it will be much more convenient to copy paste a suggested fix than retyping it or tracking down the correct usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those are good ideas. It will only work in the case that the classes, interfaces, and traits are loaded, but that is true for the functions stuff I already added. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lsmith77 What kind of research? Common incorrectly used (or missing use
statement) classes? If so, that would be pretty useful in this case. :) Is it published anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
he collected data on exceptions
Wow, really awesome job @simensen! You're a brave man for taking this on - because we knew that the implementation would have to stink a little bit by the very nature of what we're trying to do :). As I mentioned repeatedly at the conference, the class not found errors are a big issue for beginners and I find these error messages to be much much more helpful. If there are any parts of this implementation that have too much code smell (e.g. Thanks! |
@weaverryan Sure thing. :) I'm happy to discuss any of this. And yes, I knew some parts of it would raise some eyebrows. :) It really wasn't the direction I wanted to take it but I think it is a decent start. Even as-is I think that it is would provide a lot of benefit. I ran into issues with I'd like to eventually be able to have a more generic solution. This seemed like the easiest place to start. |
I've improved this PR in #8553. |
This PR was merged into the master branch. Discussion ---------- [Debug] Developer friendly Class Not Found and Undefined Function errors This is a followup of #8156 | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #8156 | License | MIT | Doc PR | n/a Here is the original description from #8156: Per a discussion with @weaverryan and others, I took a crack at enhancing the exception display for class not found errors and undefined function errors. It is not the cleanest solution but this is a work in progress to see whether or not following this path makes sense. # Class Names ## Class Not Found: Unknown Class (Global Namespace) ```php <?php new WhizBangFactory(); ``` > Attempted to load class 'WhizBangFactory' from the global namespace in foo.php line 12. Did you forget a use statement for this class? ## Class Not Found: Unknown Class (Full Namespace) ```php <?php namespace Foo\Bar; new WhizBangFactory(); ``` > Attempted to load class 'WhizBangFactory' from namespace 'Foo\Bar' in foo.php line 12. Do you need to 'use' it from another namespace? ## Class Not Found: Well Known Class (Global Namespace) ```php <?php new Request(); ``` > Attempted to load class 'Request' from the global namespace in foo.php line 12. Did you forget a use statement for this class? Perhaps you need to add 'use Symfony\Component\HttpFoundation\Request' at the top of this file? ## Class Not Found: Well Known Class (Full Namespace) ```php <?php namespace Foo\Bar; new Request(); ``` > Attempted to load class 'Request' from namespace 'Foo\Bar' in foo.php line 12. Do you need to 'use' it from another namespace? Perhaps you need to add 'use Symfony\Component\HttpFoundation\Request' at the top of this file? # Functions ## Undefined Function (Global Namespace) ```php <?php // example.php: // namespace Acme\Example; // function test_namespaced_function() // { // } include "example.php"; test_namespaced_function() ``` > Attempted to call function 'test_namespaced_function' from the global namespace in foo.php line 12. Did you mean to call: '\acme\example\test_namespaced_function'? ## Undefined Function (Full Namespace) ```php <?php namespace Foo\Bar\Baz; // example.php: // namespace Acme\Example; // function test_namespaced_function() // { // } include "example.php"; test_namespaced_function() ``` > Attempted to call function 'test_namespaced_function' from namespace 'Foo\Bar\Baz' in foo.php line 12. Did you mean to call: '\acme\example\test_namespaced_function'? ## Undefined Function: Unknown Function (Global Namespace) ```php <?php test_namespaced_function() ``` > Attempted to call function 'test_namespaced_function' from the global namespace in foo.php line 12. ## Undefined Function: Unknown Function (Full Namespace) ```php <?php namespace Foo\Bar\Baz; test_namespaced_function() ``` > Attempted to call function 'test_namespaced_function' from namespace 'Foo\Bar\Baz' in foo.php line 12. Commits ------- bde67f0 fixed an error message 80e19e2 [Debug] added some missing phpdocs 968764b [Debug] refactored unit tests cefa1b5 [Debug] moved special fatal error handlers to their own classes 53ab284 [Debug] made Debug find FQCN automatically based on well-known autoloaders 208ca5f [Debug] made guessing of possible class names more flexible a0b1585 [Debug] fixed CS 6671945 Developer friendly Class Not Found and Undefined Function errors.
Per a discussion with @weaverryan and others, I took a crack at enhancing the exception display for class not found errors and undefined function errors. It is not the cleanest solution but this is a work in progress to see whether or not following this path makes sense.
Class Names
Class Not Found: Unknown Class (Global Namespace)
Class Not Found: Unknown Class (Full Namespace)
Class Not Found: Well Known Class (Global Namespace)
Class Not Found: Well Known Class (Full Namespace)
Functions
Undefined Function (Global Namespace)
Undefined Function (Full Namespace)
Undefined Function: Unknown Function (Global Namespace)
Undefined Function: Unknown Function (Full Namespace)