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

Skip to content

Improving autowire exception when you type-hint a class & alias is available #22648

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

Merged
merged 1 commit into from
May 5, 2017

Conversation

weaverryan
Copy link
Member

@weaverryan weaverryan commented May 5, 2017

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

Suppose you type-hint a class instead of the correct interface (which is aliased):

public function __construct(Logger $logger)

Current error:

Cannot autowire service "AppBundle\Security\PostVoter": argument "$logger" of method "__construct()" references class "Symfony\Bridge\Monolog\Logger" but no such service exists. You should maybe alias this class to one of these existing services: "monolog.logger", "monolog.logger.request", "monolog.logger.console", "monolog.logger.cache", "monolog.logger.templating", "monolog.logger.translation", "monolog.logger.profiler", "monolog.logger.php", "monolog.logger.event", "monolog.logger.router", "monolog.logger.security", "monolog.logger.doctrine"; or type-hint against interface "Psr\Log\LoggerInterface" instead.

New error:

Cannot autowire service "AppBundle\Security\PostVoter": argument "$logger" of method "__construct()" references class "Symfony\Bridge\Monolog\Logger" but no such service exists. Try changing the type-hint to "Psr\Log\LoggerInterface" instead.

The correct "suggestion" was always there (at the end). I think if there is already a definitive alias available for your type-hint, we can say that they are simply using the wrong type-hint and suggest only that.

$message .= sprintf('or %s "%s"', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);
$message .= sprintf('or %s "%s".', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);

return $message;
} elseif ($aliases) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be turned to an "if"

@@ -500,4 +494,28 @@ private static function getResourceMetadataForMethod(\ReflectionMethod $method)

return $methodArgumentsMetadata;
}

private function getAliasesSuggestionForType($type)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's move that up before getResourceMetadataForMethod

@@ -701,9 +723,9 @@ public function provideNotWireableCalls()

/**
* @group legacy
* @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. You should rename (or alias) the "i" service to "Symfony\Component\DependencyInjection\Tests\Compiler\I" instead.
* @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. Try changing the type-hint to "Symfony\Component\DependencyInjection\Tests\Compiler\IInterface" instead.
Copy link
Member

@nicolas-grekas nicolas-grekas May 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure about that one: the previous was contextual (about the "i" service)
the new message is not: "which type hint wtf?"

@@ -945,7 +1010,7 @@ public function setFoo(Foo $foo)
// should be called
}

/** @inheritdoc*/
/** {@inheritdoc}*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👎 that was not an error

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fabbot!

$message .= sprintf(' You should %s the "%s" service to "%s" instead.', isset($this->types[$this->types[$type]]) ? 'alias' : 'rename (or alias)', $this->types[$type], $type);
}

@trigger_error($message, E_USER_DEPRECATED);
Copy link
Member

@nicolas-grekas nicolas-grekas May 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm mixed on this one. The current message tells about the target service. The new message about the source one, but gives little info about it.
Even if we fix that, it means we won't be able to aggregate deprecation notices as we usually do. People will get a bunch of different messages for different sources, all related to the same target service in fact.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am working on improving the message - you're right in another comment about there being no context (latest commit is at least partially there - you can see the before/after in the PR comment). I may need to tweak it a bit more still.

And this is a fair point. It's interesting... because telling them to alias (e.g. EntityManager -> EntityManagerInterface) is a really easy, global fix. But it's... sorta "wrong", since we're encouraging people to allow themselves to type to the class. But... if they're the ones doing it... is it such a big deal? If we think it's not such a big deal, then I think we should indeed revert to the old message.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should revert: the deprecation notices should just tell about how to fix the forward path and make the app work in the next major with as little changes as possible.

@weaverryan weaverryan force-pushed the autowire-suggest-interface branch from 8cc5f71 to 5a3c156 Compare May 5, 2017 15:28
@weaverryan
Copy link
Member Author

FYI - fabbot failure is false

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@nicolas-grekas nicolas-grekas added this to the 3.3 milestone May 5, 2017
@fabpot
Copy link
Member

fabpot commented May 5, 2017

Thank you @weaverryan.

@fabpot fabpot merged commit 5a3c156 into symfony:master May 5, 2017
fabpot added a commit that referenced this pull request May 5, 2017
…& alias is available (weaverryan)

This PR was merged into the 3.3-dev branch.

Discussion
----------

Improving autowire exception when you type-hint a class & alias is available

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

Suppose you type-hint a class instead of the correct interface (which is aliased):

```php
public function __construct(Logger $logger)
```

Current error:

> Cannot autowire service "AppBundle\Security\PostVoter": argument "$logger" of method "__construct()" references class "Symfony\Bridge\Monolog\Logger" but no such service exists. You should maybe alias this class to one of these existing services: "monolog.logger", "monolog.logger.request", "monolog.logger.console", "monolog.logger.cache", "monolog.logger.templating", "monolog.logger.translation", "monolog.logger.profiler", "monolog.logger.php", "monolog.logger.event", "monolog.logger.router", "monolog.logger.security", "monolog.logger.doctrine"; or type-hint against interface "Psr\Log\LoggerInterface" instead.

New error:

> Cannot autowire service "AppBundle\Security\PostVoter": argument "$logger" of method "__construct()" references class "Symfony\Bridge\Monolog\Logger" but no such service exists. Try changing the type-hint to "Psr\Log\LoggerInterface" instead.

The correct "suggestion" was always  there (at the end). I think if there is already a definitive alias available for your type-hint, we can say that they are simply using the wrong type-hint and suggest *only* that.

Commits
-------

5a3c156 Improving autowire exception when you type-hint a class and there is an interface alias available
@weaverryan weaverryan deleted the autowire-suggest-interface branch May 5, 2017 17:07
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.

4 participants