Skip to content

Commit 75389f6

Browse files
lemoinemfabpot
authored andcommitted
[OptionsResolver] Fix catched exception along the dependency tree mistakenly detects cyclic dependencies
1 parent 0240d76 commit 75389f6

File tree

2 files changed

+63
-3
lines changed

2 files changed

+63
-3
lines changed

OptionsResolver.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -854,8 +854,13 @@ public function offsetGet($option)
854854
// dependency
855855
// BEGIN
856856
$this->calling[$option] = true;
857-
foreach ($this->lazy[$option] as $closure) {
858-
$value = $closure($this, $value);
857+
try {
858+
foreach ($this->lazy[$option] as $closure) {
859+
$value = $closure($this, $value);
860+
}
861+
} catch (\Exception $e) {
862+
unset($this->calling[$option]);
863+
throw $e;
859864
}
860865
unset($this->calling[$option]);
861866
// END
@@ -953,7 +958,12 @@ public function offsetGet($option)
953958
// dependency
954959
// BEGIN
955960
$this->calling[$option] = true;
956-
$value = $normalizer($this, $value);
961+
try {
962+
$value = $normalizer($this, $value);
963+
} catch (\Exception $e) {
964+
unset($this->calling[$option]);
965+
throw $e;
966+
}
957967
unset($this->calling[$option]);
958968
// END
959969
}

Tests/OptionsResolver2Dot6Test.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,56 @@ public function testFailIfCyclicDependencyBetweenNormalizerAndLazyOption()
11031103
$this->resolver->resolve();
11041104
}
11051105

1106+
public function testCatchedExceptionFromNormalizerDoesNotCrashOptionResolver()
1107+
{
1108+
$throw = true;
1109+
1110+
$this->resolver->setDefaults(array('catcher' => null, 'thrower' => null));
1111+
1112+
$this->resolver->setNormalizer('catcher', function (Options $options) {
1113+
try {
1114+
return $options['thrower'];
1115+
} catch(\Exception $e) {
1116+
return false;
1117+
}
1118+
});
1119+
1120+
$this->resolver->setNormalizer('thrower', function (Options $options) use (&$throw) {
1121+
if ($throw) {
1122+
$throw = false;
1123+
throw new \UnexpectedValueException('throwing');
1124+
}
1125+
1126+
return true;
1127+
});
1128+
1129+
$this->resolver->resolve();
1130+
}
1131+
1132+
public function testCatchedExceptionFromLazyDoesNotCrashOptionResolver()
1133+
{
1134+
$throw = true;
1135+
1136+
$this->resolver->setDefault('catcher', function (Options $options) {
1137+
try {
1138+
return $options['thrower'];
1139+
} catch(\Exception $e) {
1140+
return false;
1141+
}
1142+
});
1143+
1144+
$this->resolver->setDefault('thrower', function (Options $options) use (&$throw) {
1145+
if ($throw) {
1146+
$throw = false;
1147+
throw new \UnexpectedValueException('throwing');
1148+
}
1149+
1150+
return true;
1151+
});
1152+
1153+
$this->resolver->resolve();
1154+
}
1155+
11061156
public function testInvokeEachNormalizerOnlyOnce()
11071157
{
11081158
$calls = 0;

0 commit comments

Comments
 (0)