8000 [PropertyAccess] Show property path in all exception messages · guilhermeblanco/symfony@b286863 · GitHub
[go: up one dir, main page]

Skip to content

Commit b286863

Browse files
mpajunenfabpot
authored andcommitted
[PropertyAccess] Show property path in all exception messages
1 parent 54e07c9 commit b286863

File tree

7 files changed

+93
-9
lines changed

7 files changed

+93
-9
lines changed

UPGRADE-2.7.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,25 @@ Serializer
8383
$nameConverter = new CamelCaseToSnakeCaseNameConverter(array('fooBar', 'barFoo'));
8484
$normalizer = new GetSetMethodNormalizer(null, $nameConverter);
8585
```
86+
87+
PropertyAccess
88+
--------------
89+
90+
* `UnexpectedTypeException` now expects three constructor arguments: The invalid property value,
91+
the `PropertyPathInterface` object and the current index of the property path.
92+
93+
Before:
94+
95+
```php
96+
use Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException;
97+
98+
new UnexpectedTypeException($value, $expectedType);
99+
```
100+
101+
After:
102+
103+
```php
104+
use Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException;
105+
106+
new UnexpectedTypeException($value, $path, $pathIndex);
107+
```

src/Symfony/Component/PropertyAccess/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
2.7.0
5+
------
6+
7+
* `UnexpectedTypeException` now expects three constructor arguments: The invalid property value,
8+
the `PropertyPathInterface` object and the current index of the property path.
9+
410
2.5.0
511
------
612

src/Symfony/Component/PropertyAccess/Exception/UnexpectedTypeException.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,40 @@
1111

1212
namespace Symfony\Component\PropertyAccess\Exception;
1313

14+
use Symfony\Component\PropertyAccess\PropertyPathInterface;
15+
1416
/**
1517
* Thrown when a value does not match an expected type.
1618
*
1719
* @author Bernhard Schussek <bschussek@gmail.com>
1820
*/
1921
class UnexpectedTypeException extends RuntimeException
2022
{
21-
public function __construct($value, $expectedType)
23+
/**
24+
* @param mixed $value The unexpected value found while traversing property path
25+
* @param PropertyPathInterface $path The property path
26+
* @param int $pathIndex The property path index when the unexpected value was found
27+
*/
28+
public function __construct($value, $path, $pathIndex = null)
2229
{
23-
parent::__construct(sprintf('Expected argument of type "%s", "%s" given', $expectedType, is_object($value) ? get_class($value) : gettype($value)));
30+
if (func_num_args() === 3 && $path instanceof PropertyPathInterface) {
31+
$message = sprintf(
32+
'PropertyAccessor requires a graph of objects or arrays to operate on, '.
33+
'but it found type "%s" while trying to traverse path "%s" at property "%s".',
34+
gettype($value),
35+
(string) $path,
36+
$path->getElement($pathIndex)
37+
);
38+
} else {
39+
trigger_error('The '.__CLASS__.' constructor now expects 3 arguments: the invalid property value, the '.__NAMESPACE__.'\PropertyPathInterface object and the current index of the property path.', E_USER_DEPRECATED);
40+
41+
$message = sprintf(
42+
'Expected argument of type "%s", "%s" given',
43+
$path,
44+
is_object($value) ? get_class($value) : gettype($value)
45+
);
46+
}
47+
48+
parent::__construct($message);
2449
}
2550
}

src/Symfony/Component/PropertyAccess/PropertyAccessor.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public function setValue(&$objectOrArray, $propertyPath, $value)
9797

9898
if ($overwrite) {
9999
if (!is_object($objectOrArray) && !is_array($objectOrArray)) {
100-
throw new UnexpectedTypeException($objectOrArray, 'object or array');
100+
throw new UnexpectedTypeException($objectOrArray, $propertyPath, $i);
101101
}
102102

103103
$property = $propertyPath->getElement($i);
@@ -221,7 +221,7 @@ private function &readPropertiesUntil(&$objectOrArray, PropertyPathInterface $pr
221221

222222
for ($i = 0; $i < $lastIndex; ++$i) {
223223
if (!is_object($objectOrArray) && !is_array($objectOrArray)) {
224-
throw new UnexpectedTypeException($objectOrArray, 'object or array');
224+
throw new UnexpectedTypeException($objectOrArray, $propertyPath, $i);
225225
}
226226

227227
$property = $propertyPath->getElement($i);

src/Symfony/Component/PropertyAccess/PropertyPath.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111

1212
namespace Symfony\Component\PropertyAccess;
1313

14+
use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException;
1415
use Symfony\Component\PropertyAccess\Exception\InvalidPropertyPathException;
1516
use Symfony\Component\PropertyAccess\Exception\OutOfBoundsException;
16-
use Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException;
1717

1818
/**
1919
* Default implementation of {@link PropertyPathInterface}.
@@ -70,7 +70,7 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface
7070
*
7171
* @param PropertyPath|string $propertyPath The property path as string or instance
7272
*
73-
* @throws UnexpectedTypeException If the given path is not a string
73+
* @throws InvalidArgumentException If the given path is not a string
7474
* @throws InvalidPropertyPathException If the syntax of the property path is not valid
7575
*/
7676
public function __construct($propertyPath)
@@ -87,7 +87,12 @@ public function __construct($propertyPath)
8787
return;
8888
}
8989
if (!is_string($propertyPath)) {
90-
throw new UnexpectedTypeException($propertyPath, 'string or Symfony\Component\PropertyAccess\PropertyPath');
90+
throw new InvalidArgumentException(sprintf(
91+
'The property path constructor needs a string or an instance of '.
92+
'"Symfony\Component\PropertyAccess\PropertyPath". '.
93+
'Got: "%s"',
94+
is_object($propertyPath) ? get_class($propertyPath) : gettype($propertyPath)
95+
));
9196
}
9297

9398
if ('' === $propertyPath) {

src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ public function testGetValueReadsMagicCallThatReturnsConstant()
139139

140140
/**
141141
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
142+
* @expectedExceptionMessage PropertyAccessor requires a graph of objects or arrays to operate on, but it found type "string" while trying to traverse path "foobar" at property "foobar".
142143
*/
143144
public function testGetValueThrowsExceptionIfNotObjectOrArray()
144145
{
@@ -147,6 +148,7 @@ public function testGetValueThrowsExceptionIfNotObjectOrArray()
147148

148149
/**
149150
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
151+
* @expectedExceptionMessage PropertyAccessor requires a graph of objects or arrays to operate on, but it found type "NULL" while trying to traverse path "foobar" at property "foobar".
150152
*/
151153
public function testGetValueThrowsExceptionIfNull()
152154
{
@@ -155,12 +157,22 @@ public function testGetValueThrowsExceptionIfNull()
155157

156158
/**
157159
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
160+
* @expectedExceptionMessage PropertyAccessor requires a graph of objects or arrays to operate on, but it found type "string" while trying to traverse path "foobar" at property "foobar".
158161
*/
159162
public function testGetValueThrowsExceptionIfEmpty()
160163
{
161164
$this->propertyAccessor->getValue('', 'foobar');
162165
}
163166

167+
/**
168+
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
169+
* @expectedExceptionMessage PropertyAccessor requires a graph of objects or arrays to operate on, but it found type "NULL" while trying to traverse path "foobar.baz" at property "baz".
170+
*/
171+
public function testGetValueNestedExceptionMessage()
172+
{
173+
$this->propertyAccessor->getValue((object) array('foobar' => null), 'foobar.baz');
174+
}
175+
164176
/**
165177
* @dataProvider getValidPropertyPaths
166178
*/
@@ -249,6 +261,7 @@ public function testSetValueUpdatesMagicCallIfEnabled()
249261

250262
/**
251263
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
264+
* @expectedExceptionMessage PropertyAccessor requires a graph of objects or arrays to operate on, but it found type "string" while trying to traverse path "foobar" at property "foobar".
252265
*/
253266
public function testSetValueThrowsExceptionIfNotObjectOrArray()
254267
{
@@ -259,6 +272,7 @@ public function testSetValueThrowsExceptionIfNotObjectOrArray()
259272

260273
/**
261274
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
275+
* @expectedExceptionMessage PropertyAccessor requires a graph of objects or arrays to operate on, but it found type "NULL" while trying to traverse path "foobar" at property "foobar".
262276
*/
263277
public function testSetValueThrowsExceptionIfNull()
264278
{
@@ -269,6 +283,7 @@ public function testSetValueThrowsExceptionIfNull()
269283

270284
/**
271285
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
286+
* @expectedExceptionMessage PropertyAccessor requires a graph of objects or arrays to operate on, but it found type "string" while trying to traverse path "foobar" at property "foobar".
272287
*/
273288
public function testSetValueThrowsExceptionIfEmpty()
274289
{
@@ -277,6 +292,17 @@ public function testSetValueThrowsExceptionIfEmpty()
277292
$this->propertyAccessor->setValue($value, 'foobar', 'bam');
278293
}
279294

295+
/**
296+
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
297+
* @expectedExceptionMessage PropertyAccessor requires a graph of objects or arrays to operate on, but it found type "NULL" while trying to traverse path "foobar.baz" at property "baz".
298+
*/
299+
public function testSetValueNestedExceptionMessage()
300+
{
301+
$value = (object) array('foobar' => null);
302+
303+
$this->propertyAccessor->setValue($value, 'foobar.baz', 'bam');
304+
}
305+
280306
public function testGetValueWhenArrayValueIsNull()
281307
{
282308
$this->propertyAccessor = new PropertyAccessor(false, true);

src/Symfony/Component/PropertyAccess/Tests/PropertyPathTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,15 @@ public function testPathCannotBeEmpty()
6969
}
7070

7171
/**
72-
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
72+
* @expectedException \Symfony\Component\PropertyAccess\Exception\InvalidArgumentException
7373
*/
7474
public function testPathCannotBeNull()
7575
{
7676
new PropertyPath(null);
7777
}
7878

7979
/**
80-
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
80+
* @expectedException \Symfony\Component\PropertyAccess\Exception\InvalidArgumentException
8181
*/
8282
public function testPathCannotBeFalse()
8383
{

0 commit comments

Comments
 (0)
0