Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[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

Closed
wants to merge 1 commit into from

Conversation

simensen
Copy link
Contributor

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets n/a
License MIT
Doc PR n/a

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
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
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
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
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
// 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
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
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
namespace Foo\Bar\Baz;

test_namespaced_function()

Attempted to call function 'test_namespaced_function' from namespace 'Foo\Bar\Baz' in foo.php line 12.

@@ -40,6 +42,11 @@ class ErrorHandler
E_PARSE => 'Parse',
);

private $classNameToUseStatementSuggestions = array(
'Request' => 'Symfony\Component\HttpFoundation\Request',
'Response' => 'Symfony\Component\HttpFoundation\Response',
Copy link
Member

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 ?

Copy link
Contributor Author

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:

  1. Build a static class map for all of the Symfony components that might be installed
  2. Do some analysis/poll for classes that people frequently forget to use and just expand a smaller curated list
  3. 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.

Copy link
Contributor

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

Copy link
Contributor

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.

Copy link
Contributor Author

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. :)

Copy link
Contributor Author

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?

Copy link
Contributor

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

@weaverryan
Copy link
Member

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. $classNameToUseStatementSuggestions), then hopefully we can identify those, delay them until later, and get a merge.

Thanks!

@simensen
Copy link
Contributor Author

@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 FlattenException that made parts of this even less desirable than I expected. I wanted to have ClassNotFoundException to be aware of the fully qualified class name, class name, and namespace prefix so that the actual ExceptionHandler decoration could be smarter but I don't understand enough about FlattenException, or what it is needed, to work that angle. Yet.

I'd like to eventually be able to have a more generic solution. This seemed like the easiest place to start.

@fabpot
Copy link
Member

fabpot commented Jul 24, 2013

I've improved this PR in #8553.

@fabpot fabpot closed this Jul 24, 2013
fabpot added a commit that referenced this pull request Jul 29, 2013
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants