10000 Fix an error message to be more accurate · symfony/symfony@1be68a7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1be68a7

Browse files
committed
Fix an error message to be more accurate
1 parent 0c77296 commit 1be68a7

File tree

2 files changed

+30
-23
lines changed

2 files changed

+30
-23
lines changed

src/Symfony/Component/OptionsResolver/OptionsResolver.php

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,7 @@ public function offsetGet($option/*, bool $triggerDeprecation = true*/)
917917

918918
// Validate the type of the resolved option
919919
if (isset($this->allowedTypes[$option])) {
920-
$valid = false;
920+
$valid = true;
921921
$invalidTypes = [];
922922

923923
foreach ($this->allowedTypes[$option] as $type) {
@@ -929,13 +929,18 @@ public function offsetGet($option/*, bool $triggerDeprecation = true*/)
929929
}
930930

931931
if (!$valid) {
932-
$keys = array_keys($invalidTypes);
933-
934-
if (1 === \count($keys) && '[]' === substr($keys[0], -2)) {
935-
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $option, $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), $keys[0]));
932+
$fmtActualValue = $this->formatValue($value);
933+
$fmtAllowedTypes = implode('" or "', $this->allowedTypes[$option]);
934+
$fmtProvidedTypes = implode('|', array_keys($invalidTypes));
935+
$allowedContainsArrayType = \count(array_filter($this->allowedTypes[$option], static function ($item) {
936+
return '[]' === substr(self::$typeAliases[$item] ?? $item, -2);
937+
})) > 0;
938+
939+
if (\is_array($value) && $allowedContainsArrayType) {
940+
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $option, $fmtActualValue, $fmtAllowedTypes, $fmtProvidedTypes));
936941
}
937942

938-
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but is of type "%s".', $option, $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), implode('|', array_keys($invalidTypes))));
943+
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but is of type "%s".', $option, $fmtActualValue, $fmtAllowedTypes, $fmtProvidedTypes));
939944
}
940945
}
941946

@@ -1040,26 +1045,23 @@ private function verifyTypes(string $type, $value, array &$invalidTypes, int $le
10401045
{
10411046
if (\is_array($value) && '[]' === substr($type, -2)) {
10421047
$type = substr($type, 0, -2);
1048+
$valid = true;
10431049

10441050
foreach ($value as $val) {
10451051
if (!$this->verifyTypes($type, $val, $invalidTypes, $level + 1)) {
1046-
return false;
1052+
$valid = false;
10471053
}
10481054
}
10491055

1050-
return true;
1056+
return $valid;
10511057
}
10521058

10531059
if (('null' === $type && null === $value) || (\function_exists($func = 'is_'.$type) && $func($value)) || $value instanceof $type) {
10541060
return true;
10551061
}
10561062

1057-
if (!$invalidTypes) D7AE {
1058-
$suffix = '';
1059-
while (\strlen($suffix) < $level * 2) {
1060-
$suffix .= '[]';
1061-
}
1062-
$invalidTypes[$this->formatTypeOf($value).$suffix] = true;
1063+
if (!$invalidTypes || $level > 0) {
1064+
$invalidTypes[$this->formatTypeOf($value)] = true;
10631065
}
10641066

10651067
return false;

src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ public function testFailIfSetAllowedTypesFromLazyOption()
776776
public function testResolveFailsIfInvalidTypedArray()
777777
{
778778
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
779-
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime[]".');
779+
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime".');
780780
$this->resolver->setDefined('foo');
781781
$this->resolver->setAllowedTypes('foo', 'int[]');
782782

@@ -796,7 +796,7 @@ public function testResolveFailsWithNonArray()
796796
public function testResolveFailsIfTypedArrayContainsInvalidTypes()
797797
{
798798
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
799-
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass[]".');
799+
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass|array|DateTime".');
800800
$this->resolver->setDefined('foo');
801801
$this->resolver->setAllowedTypes('foo', 'int[]');
802802
$values = range(1, 5);
@@ -811,7 +811,7 @@ public function testResolveFailsIfTypedArrayContainsInvalidTypes()
811811
public function testResolveFailsWithCorrectLevelsButWrongScalar()
812812
{
813813
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
814-
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double[][]".');
814+
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double".');
815815
$this->resolver->setDefined('foo');
816816
$this->resolver->setAllowedTypes('foo', 'int[][]');
817817

@@ -847,6 +847,11 @@ public function provideInvalidTypes()
847847
[42, 'string', 'The option "option" with value 42 is expected to be of type "string", but is of type "integer".'],
848848
[null, 'string', 'The option "option" with value null is expected to be of type "string", but is of type "NULL".'],
849849
['bar', '\stdClass', 'The option "option" with value "bar" is expected to be of type "\stdClass", but is of type "string".'],
850+
[['foo', 12], 'string[]', 'The option "option" with value array is expected to be of type "string[]", but one of the elements is of type "integer".'],
851+
[123, ['string[]', 'string'], 'The option "option" with value 123 is expected to be of type "string[]" or "string", but is of type "integer".'],
852+
[[null], ['string[]', 'string'], 'The option "option" with value array is expected to be of type "string[]" or "string", but one of the elements is of type "NULL".'],
853+
[['string', null], ['string[]', 'string'], 'The option "option" with value array is expected to be of type "string[]" or "string", but one of the elements is of type "NULL".'],
854+
[[\stdClass::class], ['string'], 'The option "option" with value array is expected to be of type "string", but is of type "array".'],
850855
];
851856
}
852857

@@ -1898,7 +1903,7 @@ public function testNested2Arrays()
18981903
public function testNestedArraysException()
18991904
{
19001905
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
1901-
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer[][][][]".');
1906+
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer".');
19021907
$this->resolver->setDefined('foo');
19031908
$this->resolver->setAllowedTypes('foo', 'float[][][][]');
19041909

@@ -1916,7 +1921,7 @@ public function testNestedArraysException()
19161921
public function testNestedArrayException1()
19171922
{
19181923
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
1919-
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".');
1924+
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean|string|array".');
19201925
$this->resolver->setDefined('foo');
19211926
$this->resolver->setAllowedTypes('foo', 'int[][]');
19221927
$this->resolver->resolve([
@@ -1929,7 +1934,7 @@ public function testNestedArrayException1()
19291934
public function testNestedArrayException2()
19301935
{
19311936
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
1932-
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".');
1937+
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean|string|array".');
19331938
$this->resolver->setDefined('foo');
19341939
$this->resolver->setAllowedTypes('foo', 'int[][]');
19351940
$this->resolver->resolve([
@@ -1942,7 +1947,7 @@ public function testNestedArrayException2()
19421947
public function testNestedArrayException3()
19431948
{
19441949
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
1945-
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string[][]".');
1950+
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string|integer".');
19461951
$this->resolver->setDefined('foo');
19471952
$this->resolver->setAllowedTypes('foo', 'string[][][]');
19481953
$this->resolver->resolve([
@@ -1955,7 +1960,7 @@ public function testNestedArrayException3()
19551960
public function testNestedArrayException4()
19561961
{
19571962
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
1958-
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer[][][]".');
1963+
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer".');
19591964
$this->resolver->setDefined('foo');
19601965
$this->resolver->setAllowedTypes('foo', 'string[][][]');
19611966
$this->resolver->resolve([
@@ -1969,7 +1974,7 @@ public function testNestedArrayException4()
19691974
public function testNestedArrayException5()
19701975
{
19711976
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
1972-
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array[]".');
1977+
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array".');
19731978
$this->resolver->setDefined('foo');
19741979
$this->resolver->setAllowedTypes('foo', 'string[]');
19751980
$this->resolver->resolve([

0 commit comments

Comments
 (0)
0