Skip to content

Commit eeaa8ca

Browse files
yoeunesnicolas-grekas
authored andcommitted
[OptionsResolver] Fix missing prototype key in nested error paths
1 parent 50406ed commit eeaa8ca

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

OptionsResolver.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,11 @@ public function offsetGet(mixed $option, bool $triggerDeprecation = true): mixed
964964
$resolver = new self();
965965
$resolver->prototype = false;
966966
$resolver->parentsOptions = $this->parentsOptions;
967+
968+
if ($this->prototype && null !== $this->prototypeIndex && null !== ($parentOptionKey = array_key_last($resolver->parentsOptions))) {
969+
$resolver->parentsOptions[$parentOptionKey] .= \sprintf('[%s]', $this->prototypeIndex);
970+
}
971+
967972
$resolver->parentsOptions[] = $option;
968973
foreach ($this->nested[$option] as $closure) {
969974
$closure($resolver, $this);

Tests/OptionsResolverTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2595,4 +2595,46 @@ public function testRemoveAlsoRemovesDeprecation()
25952595
restore_error_handler();
25962596
}
25972597
}
2598+
2599+
public function testNestedPrototypeErrorPathHasFullContext()
2600+
{
2601+
$resolver = new OptionsResolver();
2602+
2603+
$resolver->setDefault('connections', static function (OptionsResolver $connResolver) {
2604+
$connResolver->setPrototype(true);
2605+
$connResolver->setRequired(['host', 'database']);
2606+
$connResolver->setDefault('user', 'root');
2607+
2608+
$connResolver->setDefault('replicas', static function (OptionsResolver $replicaResolver) {
2609+
$replicaResolver->setPrototype(true);
2610+
$replicaResolver->setRequired(['host']);
2611+
$replicaResolver->setDefault('user', 'read_only');
2612+
});
2613+
});
2614+
2615+
$this->expectException(MissingOptionsException::class);
2616+
$this->expectExceptionMessage('The required option "connections[main_db][replicas][1][host]" is missing.');
2617+
2618+
$options = [
2619+
'connections' => [
2620+
'main_db' => [
2621+
'host' => 'localhost',
2622+
'database' => 'app_db',
2623+
'replicas' => [
2624+
['host' => 'replica-01.local', 'user' => 'read_only'],
2625+
['user' => 'other_user'], // Index 1 -> "host" is missing here
2626+
],
2627+
],
2628+
'audit_db' => [
2629+
'host' => 'audit.local',
2630+
'database' => 'audit_db',
2631+
'replicas' => [
2632+
['host' => 'audit-replica.local'],
2633+
],
2634+
],
2635+
],
2636+
];
2637+
2638+
$resolver->resolve($options);
2639+
}
25982640
}

0 commit comments

Comments
 (0)