Skip to content

Commit

Permalink
ContainerBuilder: better error message when class is not instantiable (
Browse files Browse the repository at this point in the history
  • Loading branch information
matej21 authored and dg committed Apr 17, 2016
1 parent 69b056e commit bfbe003
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
11 changes: 8 additions & 3 deletions src/DI/ContainerBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -494,9 +494,14 @@ private function resolveEntityClass($entity, $recursive = [])
return $this->definitions[$service]->getImplement() ?: $this->resolveServiceClass($service, $recursive);

} elseif (is_string($entity)) {
if (!class_exists($entity) || !(new ReflectionClass($entity))->isInstantiable()) {
$name = array_slice(array_keys($recursive), -1);
throw new ServiceCreationException("Class $entity used in service '$name[0]' not found or is not instantiable.");
$name = array_slice(array_keys($recursive), -1);
if (!class_exists($entity)) {
throw new ServiceCreationException("Class $entity used in service '$name[0]' not found.");
} elseif ((new ReflectionClass($entity))->isAbstract()) {
throw new ServiceCreationException("Class $entity used in service '$name[0]' is abstract.");
} elseif (($rm = (new ReflectionClass($entity))->getConstructor()) !== NULL && !$rm->isPublic()) {
$visibility = $rm->isProtected() ? 'protected' : 'private';
throw new ServiceCreationException("Class $entity used in service '$name[0]' has $visibility constructor.");
}
return ltrim($entity, '\\');
}
Expand Down
30 changes: 28 additions & 2 deletions tests/DI/ContainerBuilder.factory.error.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ Assert::exception(function () {
$builder = new DI\ContainerBuilder;
$builder->addDefinition('one')->setClass('X')->setFactory('Unknown');
$builder->generateClasses();
}, Nette\InvalidStateException::class, "Class Unknown used in service 'one' not found or is not instantiable.");
}, Nette\InvalidStateException::class, "Class Unknown used in service 'one' not found.");


Assert::exception(function () {
$builder = new DI\ContainerBuilder;
$builder->addDefinition('one')->setFactory('@two');
$builder->addDefinition('two')->setFactory('Unknown');
$builder->generateClasses();
}, Nette\InvalidStateException::class, "Class Unknown used in service 'two' not found or is not instantiable.");
}, Nette\InvalidStateException::class, "Class Unknown used in service 'two' not found.");


Assert::exception(function () {
Expand Down Expand Up @@ -132,3 +132,29 @@ Assert::error(function () {
$builder->addDefinition('one')->setFactory('Bad7::create');
$builder->generateClasses();
}, E_USER_NOTICE, "Type of service 'one' is unknown.");


class Bad8
{
private function __construct()
{}
}

Assert::exception(function () {
$builder = new DI\ContainerBuilder;
$builder->addDefinition('one')->setClass('Bad8');
$builder->generateClasses();
}, Nette\InvalidStateException::class, "Class Bad8 used in service 'one' has private constructor.");


abstract class Bad9
{
protected function __construct()
{}
}

Assert::exception(function () {
$builder = new DI\ContainerBuilder;
$builder->addDefinition('one')->setClass('Bad9');
$builder->generateClasses();
}, Nette\InvalidStateException::class, "Class Bad9 used in service 'one' is abstract.");

0 comments on commit bfbe003

Please sign in to comment.