schmittjoh / serializer

Library for (de-)serializing data of any complexity (supports JSON, and XML)
http://jmsyst.com/libs/serializer
MIT License
2.32k stars 589 forks source link

Is there a way to make the deserialize failed when a property is not set ? #1477

Closed Arthur-GP closed 1 year ago

Arthur-GP commented 1 year ago
Q A
Bug report? Maybe?
Feature request? depends
BC Break report? no
RFC? yes/no

Explaining the problem :

Context : I'm trying to call an API that returns a JSON. But the API always returns a json with 200 even if the request is wrongly formatted. So I wanted to try to deserialize the data into the "good result" class (APIMoodleError for the error, and APIMoodleGetUser for the valid response) and expected to see an exception occur when the request is bad cause the field of the json are not the same, and in my mind it would occure an exception at the deserialization . However, the deserialize init my property at null.

Also, I thought I could use the PostDeserialize to check if the data is empty and throw my exception that I could catch on the "try... catch under". But since it's after the deserialize it's not caught in the try catch.

My question is : "Is there a way to make the deserialize failed when a property is not set ? I couldn't find a configuration for this so I don't know if I didn't search enought or if it's simply not possible, that's why I posted this "Issue/Feature"

Steps required to reproduce the problem

  1. Create the class with annotation src/Entity/MoodleAPI/APIMoodleError.php

    class APIMoodleError {
    
    #[Serializer\Type("string")]
    private $exception; 
    
    #[Serializer\Type("string")]
    private ?string $errorcode; 
    
    #[Serializer\Type("string")]
    private $message; 
    
    /**
     * @param string $exception
     * @param string $errorcode
     * @param string $message
     */
    public function __construct(string $exception, string $errorcode, string $message) {
        $this->exception = $exception;
        $this->errorcode = $errorcode;
        $this->message = $message;
    }
     # Getter and setter defined but not show. 
    }
  2. Try to deserialize with a type in the property Trying to deserialize
    
    $result = '{"excep":"invalid_parameter_exception","errorcode":"invalidparameter","message":"Valeur incorrecte de param\u00e8tre d\u00e9tect\u00e9e"}';
    # Typo in field exception to force an error.
    try {
    $APIMoodleResult = $this->_serializer->deserialize(
        $result,
        APIMoodleGetUser::class,
        'json',
    );
    } catch (Exception $e){
    echo "Deserialization failed: " . $e->getMessage();
    }

var_dump($APIMoodleResult); object(App\Entity\MoodleAPI\APIMoodleError)#584 (3) { ["exception":"App\Entity\MoodleAPI\APIMoodleError":private]=> NULL ["errorcode":"App\Entity\MoodleAPI\APIMoodleError":private]=> string(16) "invalidparameter" ["message":"App\Entity\MoodleAPI\APIMoodleError":private]=> string(42) "Valeur incorrecte de paramètre détectée" }


## Expected Result

*  To raise a Exception
* Or a way to handle this use case

## Actual Result

```php
var_dump($APIMoodleResult); 
object(App\Entity\MoodleAPI\APIMoodleError)#584 (3) { ["exception":"App\Entity\MoodleAPI\APIMoodleError":private]=> NULL ["errorcode":"App\Entity\MoodleAPI\APIMoodleError":private]=> string(16) "invalidparameter" ["message":"App\Entity\MoodleAPI\APIMoodleError":private]=> string(42) "Valeur incorrecte de paramètre détectée" } 
scyzoryck commented 1 year ago

Hi @Arthur-GP ! If I understand correctly strict JSON deserialisation should do the job. :) See: https://github.com/schmittjoh/serializer/pull/1401

Arthur-GP commented 1 year ago

It look like it's what I want ! But i'm using the jms/serializer-bundle : ^5.5, and i can't find a way to use it.

Trying this didn't work.

$APIMoodleResult = $this->_serializer->deserialize(
            $result,
            APIMoodleUser::class,
            'strict',
        );

Can't find a reference to strict in either Bundle doc, or Serializer doc.

PS : Working with Symfony 6

Arthur-GP commented 1 year ago

Moved the subject to JMSSerializerBundle Repo