Skip to content

[DependencyInjection] Remove inaccurate @throws on Container::get() #51835

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
Oct 30, 2023

Conversation

VincentLanglet
Copy link
Contributor

@VincentLanglet VincentLanglet commented Oct 4, 2023

Q A
Branch? 6.4
Bug fix? no
New feature? no
Deprecations? no
Tickets Fix #51834
License MIT

This would solve the inconsistency between ContainerInterface and Container described in #51834 because currently the Container phpdoc doesn't respect the ContainerInterface one.

@derrabus
Copy link
Member

derrabus commented Oct 4, 2023

Wouldn't we violate PSR-11 if we upcast ServiceNotFoundException?

@VincentLanglet
Copy link
Contributor Author

Wouldn't we violate PSR-11 if we upcast ServiceNotFoundException?

Sorry, I'm not sure to understand ; can you develop ?

Currently PSR\Container\ContainerInterface have the following phpdoc:

interface ContainerInterface
{
    /**
     * Finds an entry of the container by its identifier and returns it.
     *
     * @param string $id Identifier of the entry to look for.
     *
     * @throws NotFoundExceptionInterface  No entry was found for **this** identifier.
     * @throws ContainerExceptionInterface Error while retrieving the entry.
     *
     * @return mixed Entry.
     */
    public function get(string $id);
}

So, to be PSR, Symfony should only throw NotFoundExceptionInterface and ContainerExceptionInterface.

Currently, since Symfony allows to throws \Exception in the Container::get method, in my understanding the Symfony Container doesn't fully respect the PSR interface.

The introduced ServiceLoadingException implements ContainerExceptionInterface so it will now respect the PSR interface.

@VincentLanglet VincentLanglet requested a review from stof October 4, 2023 09:19
@VincentLanglet
Copy link
Contributor Author

Is this PR ok @derrabus @stof ? I'm not sure but failures seem unrelated

@@ -199,10 +201,6 @@ public function has(string $id): bool
/**
* Gets a service.
*
* @throws ServiceCircularReferenceException When a circular reference is detected
* @throws ServiceNotFoundException When the service is not defined
* @throws \Exception if an exception has been thrown when the service has been resolved
Copy link
Member

Choose a reason for hiding this comment

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

I would simply remove this line and nothing else.

Copy link
Contributor Author

@VincentLanglet VincentLanglet Oct 27, 2023

Choose a reason for hiding this comment

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

This would kinda hide the problem.

Currently there is a reproducer in the Symfony tests:

public function testGetThrowsException()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Something went terribly wrong!');
$c = new ProjectServiceContainer();
try {
$c->get('throw_exception');
} catch (\Exception $e) {
// Do nothing.
}
// Retry, to make sure that get*Service() will be called.
$c->get('throw_exception');
}

protected function getThrowExceptionService()
{
throw new \Exception('Something went terribly wrong!');
}

Should it be Symfony responsibility to try/catch and rethrow a compliant exception or should we rely on the developer to throw the right exception ?

The first solution seemed safer

Copy link
Member

Choose a reason for hiding this comment

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

@throws is to document exceptions that can be thrown under the responbility of the called method. Re-thrown exceptions don't fit this definition so this @throws is just wrong. Wrapping them all won't provide anything more.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To me the purpose of the @throws tag is to know which Exceptions I should catch when doing

$container->get()

That's also how static analysis like PHPStan works.

But I'm ok removing the \Exception line, it solves my issue.
Pr is update

@carsonbot carsonbot changed the title Introduce ServiceLoadingException to scope Container exceptions [DependencyInjection] Introduce ServiceLoadingException to scope Container exceptions Oct 27, 2023
@nicolas-grekas nicolas-grekas changed the title [DependencyInjection] Introduce ServiceLoadingException to scope Container exceptions [DependencyInjection] Remove inaccurate @throws on Container::get() Oct 27, 2023
@nicolas-grekas
Copy link
Member

Thank you @VincentLanglet.

@nicolas-grekas nicolas-grekas merged commit 61023a7 into symfony:6.4 Oct 30, 2023
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.

[DependencyInjection] ContainerInterface::get and Container::get throws tag are not consistent
5 participants