[OptionsResolver] Fix catched exception along the dependency tree mistakenly detects cyclic dependencies

This commit is contained in:
Mathieu Lemoine 2015-09-23 15:41:05 -04:00 committed by Fabien Potencier
parent 7d674c2135
commit 9a188c5215
2 changed files with 63 additions and 3 deletions

View File

@ -854,8 +854,13 @@ class OptionsResolver implements Options, OptionsResolverInterface
// dependency
// BEGIN
$this->calling[$option] = true;
foreach ($this->lazy[$option] as $closure) {
$value = $closure($this, $value);
try {
foreach ($this->lazy[$option] as $closure) {
$value = $closure($this, $value);
}
} catch (\Exception $e) {
unset($this->calling[$option]);
throw $e;
}
unset($this->calling[$option]);
// END
@ -953,7 +958,12 @@ class OptionsResolver implements Options, OptionsResolverInterface
// dependency
// BEGIN
$this->calling[$option] = true;
$value = $normalizer($this, $value);
try {
$value = $normalizer($this, $value);
} catch (\Exception $e) {
unset($this->calling[$option]);
throw $e;
}
unset($this->calling[$option]);
// END
}

View File

@ -1103,6 +1103,56 @@ class OptionsResolver2Dot6Test extends \PHPUnit_Framework_TestCase
$this->resolver->resolve();
}
public function testCatchedExceptionFromNormalizerDoesNotCrashOptionResolver()
{
$throw = true;
$this->resolver->setDefaults(array('catcher' => null, 'thrower' => null));
$this->resolver->setNormalizer('catcher', function (Options $options) {
try {
return $options['thrower'];
} catch(\Exception $e) {
return false;
}
});
$this->resolver->setNormalizer('thrower', function (Options $options) use (&$throw) {
if ($throw) {
$throw = false;
throw new \UnexpectedValueException('throwing');
}
return true;
});
$this->resolver->resolve();
}
public function testCatchedExceptionFromLazyDoesNotCrashOptionResolver()
{
$throw = true;
$this->resolver->setDefault('catcher', function (Options $options) {
try {
return $options['thrower'];
} catch(\Exception $e) {
return false;
}
});
$this->resolver->setDefault('thrower', function (Options $options) use (&$throw) {
if ($throw) {
$throw = false;
throw new \UnexpectedValueException('throwing');
}
return true;
});
$this->resolver->resolve();
}
public function testInvokeEachNormalizerOnlyOnce()
{
$calls = 0;