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

Skip to content

Conversation

@pmlt
Copy link
Contributor

@pmlt pmlt commented Nov 9, 2017

In PHP 7, it is possible to throw something that doesn't inherit the Exception class. The most common example is that type-checking now causes a TypeError to be thrown. PHP-DI did not catch this type of error, and leaves the entry dangling as "being resolved". If the service is requested again after this happens, a "Circular dependency detected while trying to resolve entry" exception is thrown by Container even though there is no circular dependency.

The solution uses a finally block instead of catch(Exception) to ensure all possible Throwables are handled properly. This also removes the need to re-throw the exception.

Minimal test case for this behavior:

class Foo
{
  public function __construct(bool $foo)
  {
  }
}
$builder = new DI\ContainerBuilder();
$builder->addDefinitions([
  Foo::class => DI\factory(function() {
    return new Foo(""); // Cause a TypeError to be thrown
  });
]);
$container = $builder->build();
try {
  $container->get(Foo::class);
} catch (Throwable $e) {
  // TypeError was caught by us but not Container
}
$container->get(Foo::class); // This will cause a circular dependency exception

Use finally block instead of catch(Exception) to ensure all kinds of
throwables are handled properly.
@mnapoli
Copy link
Member

mnapoli commented Nov 10, 2017

Thank you this is great! Would you have time to add a test for this in tests/IntegrationTest/CircularDependencyTest.php?

@mnapoli mnapoli added this to the 6.0 milestone Nov 10, 2017
@mnapoli mnapoli added the bug label Nov 10, 2017
@pmlt
Copy link
Contributor Author

pmlt commented Nov 10, 2017

Done! Though since fix is to avoid a false circular dependency error, I thought it best to put the test in tests/IntegrationTest/ContainerMakeTest.php instead.

@mnapoli
Copy link
Member

mnapoli commented Nov 10, 2017

Awesome thanks!

@mnapoli mnapoli merged commit bc7d1aa into PHP-DI:master Nov 10, 2017
throw $exception;
}

unset($this->entriesBeingResolved[$entryName]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this line really necessary anymore?

Copy link
Member

Choose a reason for hiding this comment

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

Good catch I've removed it on master thanks

mnapoli added a commit that referenced this pull request Nov 11, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants