Jmsserializerbundle: NotAcceptableException when serializing null

Created on 11 Mar 2020  路  18Comments  路  Source: schmittjoh/JMSSerializerBundle

When serialize_null: false:

jms_serializer:
    default_context:
        serialization:
            serialize_null: false

And one tries to serialize null, JMS version 3.0 started throwing:

JMS\Serializer\Exception\NotAcceptableException:

  at vendor/jms/serializer/src/GraphNavigator/SerializationGraphNavigator.php:136
  at JMS\Serializer\GraphNavigator\SerializationGraphNavigator->accept(null, array('name' => 'NULL', 'params' => array()))
     (vendor/jms/serializer/src/Serializer.php:249)
  at JMS\Serializer\Serializer->visit(object(SerializationGraphNavigator), object(JsonSerializationVisitor), object(SerializationContext), null, 'json', null)
     (vendor/jms/serializer/src/Serializer.php:162)
  at JMS\Serializer\Serializer->serialize(null, 'json', object(SerializationContext))

This was not the case in the older versions.

Is there a way to prevent this error, but still be able to prevent serializing null values at a deeper levels of json structures? Which means keep serialize_null: false so resulting json does not contain nulls.

Most helpful comment

All 18 comments

Hi, I understand the issue, this was an announced BC break in 2.0.

What would be the expected result here?
When serialize_null: false, it says do not serialize nulls, so when the "root" element is already a NULL, the only possible thing to do is to throw exception....

The only backward compatible solution I see is to add a parameter in the serialization-context like allows_root_null that will override the serialize_null: false only for the root object.

Do you have other suggestions?

The only backward compatible solution I see is to add a parameter in the serialization-context like allows_root_null that will override the serialize_null: false only for the root object.

If you are ok with this solution, I will be happy to accept a pull request.

I don't think that will solve the issue. I think the problem here is using exceptions for flow control. Don't serialize nulls does not means blow my app. :)

If I call serialize(null) I do want to serialize it. From my point of view, it should always serialize nulls if they are at root level.

calling serialize(null) contradicts the initial serialize_null: false setting, that is the reason of the exception.

I agree, but it contradicted in version 1.0 too. If this is a BC break we need to live with, it will cause lots of changes like this:

- $s = serialize($v);
+ if (null === $v) {
+     $s = 'null';
+ } else {
+     $s = serialize($v);
+ }

It's similar in twig when serialize filter is used.

I understand, but I think that the solution proposed in https://github.com/schmittjoh/JMSSerializerBundle/issues/788#issuecomment-598123991 can help.

You can combine it with the default serialization context,

jms_serializer:
    default_context:
        serialization:
            serialize_null: false
            attributes: 
                allows_root_null: true

In this way no other code changes are needed

This is perfect, thanks!

Since the issue is not solved and https://github.com/schmittjoh/JMSSerializerBundle/issues/788#issuecomment-598189892 just proposes a solution, i'm re opening the ticket

@goetas I tried allows_root_null now with jms/serializer 3.8.0 and jms/serializer-bundle 3.7.0 and it didn't work. I can;t find it in the code neither. Is it removed?

https://github.com/schmittjoh/JMSSerializerBundle/issues/788#issuecomment-598189892 is just a proposal for a solution, it has not been implemented

Oh, I see.

Well, since this is a blocker for me, I'm interested to help.

If you give me some directions I'd be interested to contribute.

That is a good news.
That we need to do is to add an extra check in https://github.com/schmittjoh/serializer/blob/4fe470c179ae8da9e243dd8fac6c0fc2302d9378/src/GraphNavigator/SerializationGraphNavigator.php#L136

something like

if ($this->context->getAttribute('allows_root_null') && $isRootObject) {
    return NULL;
}

to $isRootObject should be possible to calculate by looking at the size of https://github.com/schmittjoh/serializer/blob/4fe470c179ae8da9e243dd8fac6c0fc2302d9378/src/SerializationContext.php#L137

Thanks, so $isRootObject = 0 === $this->context->getVisitingSet()->count()?

i guess so... but tests should uncover eventual bugs

It worked pretty well, PR created https://github.com/schmittjoh/serializer/pull/1248. Thanks.

Could the bundle be updated to 3.9 so we can use this attribute ? thanks

Was this page helpful?
0 / 5 - 0 ratings

Related issues

VincentClair picture VincentClair  路  8Comments

Chrysweel picture Chrysweel  路  7Comments

egonolieux picture egonolieux  路  4Comments

thaonx picture thaonx  路  5Comments

CsabaNa picture CsabaNa  路  3Comments