diff --git a/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php b/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php index 37d95861414bf..c5c88d28046e4 100644 --- a/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php +++ b/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php @@ -275,19 +275,22 @@ public function setTraceFromThrowable(\Throwable $throwable): self /** * @return $this */ - public function setTrace($trace, $file, $line): self + public function setTrace($trace, $file = null, $line = null): self { $this->trace = []; - $this->trace[] = [ - 'namespace' => '', - 'short_class' => '', - 'class' => '', - 'type' => '', - 'function' => '', - 'file' => $file, - 'line' => $line, - 'args' => [], - ]; + if (null !== $file) { + $this->trace[] = [ + 'namespace' => '', + 'short_class' => '', + 'class' => '', + 'type' => '', + 'function' => '', + 'file' => $file, + 'line' => $line, + 'args' => [], + ]; + } + foreach ($trace as $entry) { $class = ''; $namespace = ''; @@ -357,6 +360,18 @@ private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value): str public function getTraceAsString(): string { + if (null === $this->traceAsString) { + $this->traceAsString = ''; + if (null !== $this->trace) { + foreach ($this->trace as $i => $trace) { + if (0 === $i) { + continue; + } + $this->traceAsString .= sprintf('#%d %s(%s): %s%s%s()', $i - 1, $trace['file'], $trace['line'], $trace['class'], $trace['type'], $trace['function']).\PHP_EOL; + } + } + } + return $this->traceAsString; } diff --git a/src/Symfony/Component/ErrorHandler/Tests/Exception/FlattenExceptionTest.php b/src/Symfony/Component/ErrorHandler/Tests/Exception/FlattenExceptionTest.php index 30c5234669adf..fad4ad3808ee0 100644 --- a/src/Symfony/Component/ErrorHandler/Tests/Exception/FlattenExceptionTest.php +++ b/src/Symfony/Component/ErrorHandler/Tests/Exception/FlattenExceptionTest.php @@ -29,6 +29,10 @@ use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException; +use Symfony\Component\Serializer\Encoder\JsonEncoder; +use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; +use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; +use Symfony\Component\Serializer\Serializer; class FlattenExceptionTest extends TestCase { @@ -405,6 +409,22 @@ public function testToStringParent() $this->assertSame($exception->__toString(), $flattened->getAsString()); } + public function testSerialize() + { + $serializer = new Serializer([new ArrayDenormalizer(), new ObjectNormalizer()], [new JsonEncoder()]); + + $flattened = FlattenException::createFromThrowable(new \LogicException('Bad things happened')); + $trace = $flattened->getTraceAsString(); + $data = $serializer->serialize($flattened, 'json'); + + $restored = $serializer->deserialize($data, FlattenException::class, 'json'); + $restoredTrace = $restored->getTraceAsString(); + + // Verify that they look kind of similar. + $this->assertEquals(substr($trace, 0, 100), substr($restoredTrace, 0, 100)); + $this->assertEquals(\count(explode(\PHP_EOL, $trace)), \count(explode(\PHP_EOL, $restoredTrace))); + } + private function createException($foo): \Exception { return new \Exception(); diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index d3f046a074ce4..12b1e2f38e7a3 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -610,6 +610,7 @@ private function getWriteInfo(string $class, string $property, $value): Property 'enable_magic_methods_extraction' => $this->magicMethodsFlags, 'enable_constructor_extraction' => false, 'enable_adder_remover_extraction' => $useAdderAndRemover, + 'value' => $value, ]); if (isset($item)) { diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 5287979945af3..df1058a2e7d08 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -388,6 +388,12 @@ public function getWriteInfo(string $class, string $property, array $context = [ } $method = $reflClass->getMethod($methodName); + /** @var \ReflectionParameter $parameter */ + $parameter = $method->getParameters()[0]; + if (\array_key_exists('value', $context) && null === $context['value'] && !$parameter->allowsNull()) { + $errors[] = sprintf('The method "%s" in class "%s" was found but does not allow null.', $methodName, $class); + continue; + } if (!\in_array($mutatorPrefix, $this->arrayMutatorPrefixes, true)) { return new PropertyWriteInfo(PropertyWriteInfo::TYPE_METHOD, $methodName, $this->getWriteVisiblityForMethod($method), $method->isStatic());