Skip to content

Commit

Permalink
[OptionsResolver] Fix catched exception along the dependency tree mis…
Browse files Browse the repository at this point in the history
…takenly detects cyclic dependencies
  • Loading branch information
lemoinem authored and fabpot committed Sep 25, 2015
1 parent 7d674c2 commit 9a188c5
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 3 deletions.
16 changes: 13 additions & 3 deletions src/Symfony/Component/OptionsResolver/OptionsResolver.php
Expand Up @@ -854,8 +854,13 @@ public function offsetGet($option)
// 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
Expand Down Expand Up @@ -953,7 +958,12 @@ public function offsetGet($option)
// 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
}
Expand Down
Expand Up @@ -1103,6 +1103,56 @@ public function testFailIfCyclicDependencyBetweenNormalizerAndLazyOption()
$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;
Expand Down

0 comments on commit 9a188c5

Please sign in to comment.