Skip to content

[ErrorHandler] Serialize FlattenException #38800

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

Nyholm
Copy link
Member

@Nyholm Nyholm commented Oct 25, 2020

Q A
Branch? 5.x
Bug fix? yes
New feature? no
Deprecations? no
Tickets Related to #38792
License MIT
Doc PR Not needed

The FlatternException is used with messenger. When it is serialized with the Serializer component we fail to restore all its properties.

When FlatternException::$traceAsString is null and we call FlatternException::getTraceAsString() we get an exception thrown in our face. That is what #38792 is about.

This PR does two things (sorry about that).

  1. It modifies FlatternException::setTrace() so the serializer can populate the trace property when unserializing. I also try to rebuild the traceAsString from the $trace

  2. It modifies the PropertyAccess and PropertyInfo component to be aware of nullable setters. Ie, It finds FlatternException::setPrevious(), but that function does not allow nullable parameters, but it still try to set the value null and we get another exception thrown in our face.

@Nyholm Nyholm requested a review from yceruto October 25, 2020 21:49
@Nyholm Nyholm requested a review from dunglas as a code owner October 25, 2020 21:49
@chalasr chalasr changed the title [ErrorHandler] Serialize FlatternException [ErrorHandler] Serialize FlattenException Oct 25, 2020
{
$this->trace = [];
if ($file)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that this is WIP :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to leave it after 2 hours that late last night.

I would like to get some feedback from @yceruto and/or someone that knows about property access.

Also, is it a good idea to modify a class "just because" serialization?

@nicolas-grekas nicolas-grekas added this to the 5.2 milestone Oct 26, 2020
@@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this a BC break for inheriting classes? Any other idea?

/** @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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks PropertyAccess test suite (see Travis's failure)

Copy link
Member

@yceruto yceruto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey! As far as I understand, this FlattenException should be handled by Symfony\Component\Messenger\Transport\Serialization\Normalizer\FlattenExceptionNormalizer and Symfony\Component\Messenger\Transport\Serialization\Serializer when the Messenger component is installed.

I did some tests using this code and it works without any other change:

use Symfony\Component\Messenger\Transport\Serialization\Normalizer\FlattenExceptionNormalizer;
use Symfony\Component\Messenger\Transport\Serialization\Serializer as MessengerSerializer;
// ...

public function testSerialize()
{
    $serializer = new Serializer([new FlattenExceptionNormalizer()], [new JsonEncoder()]);
    $context = [MessengerSerializer::MESSENGER_SERIALIZATION_CONTEXT => true];

    $flattened = FlattenException::createFromThrowable(new \LogicException('Bad things happened'));
    $trace = $flattened->getTraceAsString();
    $data = $serializer->serialize($flattened, 'json', $context);

    $restored = $serializer->deserialize($data, FlattenException::class, 'json', $context);
    $restoredTrace = $restored->getTraceAsString();

    $this->assertSame(substr($trace, 0, 100), substr($restoredTrace, 0, 100));
    $this->assertSame(\count(explode(\PHP_EOL, $trace)), \count(explode(\PHP_EOL, $restoredTrace)));
}

The matter is that this FlattenExceptionNormalizer doesn't exist in 5.1, but since 5.2 #37087, and the related issue is talking about this error on 5.1, but also it happens in 4.3 #32719

By the way, I can't reproduce the issue on 5.2:

Exception:
==========

(no data)

Maybe I'm missing something, but it seems AddErrorDetailsStampListener is not registered by default, hence the ErrorDetailsStamp is not added.

@Nyholm
Copy link
Member Author

Nyholm commented Nov 1, 2020

Thank you for the explanation. So we are closing this as "wontfix" for 4.4?

Maybe I'm missing something, but it seems AddErrorDetailsStampListener is not registered by default, hence the ErrorDetailsStamp is not added.

That is true. I though that was intentional... but Im not sure.

@yceruto
Copy link
Member

yceruto commented Nov 1, 2020

So we are closing this as "wontfix" for 4.4?

Well, it's possible to fix it if we use PropertyNormalizer to serialize/deserialize the FlattenException instance or backporting the FlattenExceptionNormalizer.

That is true. I though that was intentional... but Im not sure.

Ok it's being fixed here #38941.

@Nyholm
Copy link
Member Author

Nyholm commented Nov 1, 2020

Im happy with closing this issue then.

@Nyholm Nyholm closed this Nov 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants