bug #36904 [PropertyAccess] Parse php 8 TypeErrors correctly (derrabus)
This PR was merged into the 3.4 branch.
Discussion
----------
[PropertyAccess] Parse php 8 TypeErrors correctly
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | #36872
| License | MIT
| Doc PR | N/A
The wording of `TypeError` messages has changed in php 8. Since `PropertyAccessor` parses those messages, the logic needed some adjustments.
Commits
-------
7100c3ce1b
[PropertyAccess] Parse php 8 TypeErrors correctly.
This commit is contained in:
commit
e220e7cc01
@ -255,12 +255,15 @@ class PropertyAccessor implements PropertyAccessorInterface
|
|||||||
|
|
||||||
private static function throwInvalidArgumentException($message, $trace, $i, $previous = null)
|
private static function throwInvalidArgumentException($message, $trace, $i, $previous = null)
|
||||||
{
|
{
|
||||||
// the type mismatch is not caused by invalid arguments (but e.g. by an incompatible return type hint of the writer method)
|
if (!isset($trace[$i]['file']) || __FILE__ !== $trace[$i]['file']) {
|
||||||
if (0 !== strpos($message, 'Argument ')) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($trace[$i]['file']) && __FILE__ === $trace[$i]['file']) {
|
if (\PHP_VERSION_ID < 80000) {
|
||||||
|
if (0 !== strpos($message, 'Argument ')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$pos = strpos($message, $delim = 'must be of the type ') ?: (strpos($message, $delim = 'must be an instance of ') ?: strpos($message, $delim = 'must implement interface '));
|
$pos = strpos($message, $delim = 'must be of the type ') ?: (strpos($message, $delim = 'must be an instance of ') ?: strpos($message, $delim = 'must implement interface '));
|
||||||
$pos += \strlen($delim);
|
$pos += \strlen($delim);
|
||||||
$j = strpos($message, ',', $pos);
|
$j = strpos($message, ',', $pos);
|
||||||
@ -269,6 +272,12 @@ class PropertyAccessor implements PropertyAccessorInterface
|
|||||||
|
|
||||||
throw new InvalidArgumentException(sprintf('Expected argument of type "%s", "%s" given.', $message, 'NULL' === $type ? 'null' : $type), 0, $previous);
|
throw new InvalidArgumentException(sprintf('Expected argument of type "%s", "%s" given.', $message, 'NULL' === $type ? 'null' : $type), 0, $previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (preg_match('/^\S+::\S+\(\): Argument #\d+ \(\$\S+\) must be of type (\S+), (\S+) given/', $message, $matches)) {
|
||||||
|
list(, $expectedType, $actualType) = $matches;
|
||||||
|
|
||||||
|
throw new InvalidArgumentException(sprintf('Expected argument of type "%s", "%s" given.', $expectedType, 'NULL' === $actualType ? 'null' : $actualType), 0, $previous);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -471,7 +480,7 @@ class PropertyAccessor implements PropertyAccessorInterface
|
|||||||
$result[self::VALUE] = $object->{$access[self::ACCESS_NAME]}();
|
$result[self::VALUE] = $object->{$access[self::ACCESS_NAME]}();
|
||||||
} catch (\TypeError $e) {
|
} catch (\TypeError $e) {
|
||||||
// handle uninitialized properties in PHP >= 7
|
// handle uninitialized properties in PHP >= 7
|
||||||
if (preg_match((sprintf('/^Return value of %s::%s\(\) must be of the type (\w+), null returned$/', preg_quote(\get_class($object)), $access[self::ACCESS_NAME])), $e->getMessage(), $matches)) {
|
if (preg_match((sprintf('/^Return value of %s::%s\(\) must be of (?:the )?type (\w+), null returned$/', preg_quote(\get_class($object)), $access[self::ACCESS_NAME])), $e->getMessage(), $matches)) {
|
||||||
throw new AccessException(sprintf('The method "%s::%s()" returned "null", but expected type "%3$s". Did you forget to initialize a property or to make the return type nullable using "?%3$s"?', \get_class($object), $access[self::ACCESS_NAME], $matches[1]), 0, $e);
|
throw new AccessException(sprintf('The method "%s::%s()" returned "null", but expected type "%3$s". Did you forget to initialize a property or to make the return type nullable using "?%3$s"?', \get_class($object), $access[self::ACCESS_NAME], $matches[1]), 0, $e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user