Skip to content

[Form] InvalidArgumentException while using type declaration in entity #43509

@Safranil

Description

@Safranil

Symfony version(s) affected: 5.3.4

Description
I use PHP 8 and my entities use the type declaration on setter and getter.

When validating a Form with a null value on a field that require non null (eg: method(string $value)), the handle() method throw an InvalidArgumentException and a TypeError.

How to reproduce

Example Entity, Form and Controller

src/Entity/Structure.php

<?php
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

namespace App\Entity;
/**
 * @ORM\Entity()
 */
class Structure {
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBank()
     */
    private $name;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }
}

src/Form/StructureType.php

<?php

namespace App\Form;

use App\Entity\Structure;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class StructureType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Structure::class,
        ]);
    }
}

src/Controller/Structure.php

<?php

namespace App\Controller;

use App\Entity\Structure;
use App\Form\StructureType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class StructureController extends AbstractController
{

    #[Route('/test_form', name: 'test_form')]
    public function create(Request $request): Response
    {
        $structure = new Structure();
        $form = $this->createForm(StructureType::class, $structure);
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            /* ... */
        }

        return $this->render('structure/form.html.twig', [
            'form' => $form->createView(),
        ]);
    }
}

Possible Solution
Catch these exceptions and add a validation error asking a non null value (or use the existing Validator on the field)

Additional context

The stack trace when $form->handleRequest($request) is called
Symfony\Component\PropertyAccess\Exception\InvalidArgumentException:
Expected argument of type "string", "null" given at property path "name".

  at vendor/symfony/property-access/PropertyAccessor.php:268
  at Symfony\Component\PropertyAccess\PropertyAccessor::throwInvalidArgumentException()
     (vendor/symfony/property-access/PropertyAccessor.php:179)
  at Symfony\Component\PropertyAccess\PropertyAccessor->setValue()
     (vendor/symfony/form/Extension/Core/DataAccessor/PropertyPathAccessor.php:68)
  at Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor->setValue()
     (vendor/symfony/form/Extension/Core/DataAccessor/ChainAccessor.php:54)
  at Symfony\Component\Form\Extension\Core\DataAccessor\ChainAccessor->setValue()
     (vendor/symfony/form/Extension/Core/DataMapper/DataMapper.php:87)
  at Symfony\Component\Form\Extension\Core\DataMapper\DataMapper->mapFormsToData()
     (vendor/symfony/form/Form.php:640)
  at Symfony\Component\Form\Form->submit()
     (vendor/symfony/form/Extension/HttpFoundation/HttpFoundationRequestHandler.php:109)
  at Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler->handleRequest()
     (vendor/symfony/form/Form.php:501)
  at Symfony\Component\Form\Form->handleRequest()
     (src/Controller/StructureController.php:36)
  at App\Controller\StructureController->edit()
     (vendor/symfony/http-kernel/HttpKernel.php:156)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw()
     (vendor/symfony/http-kernel/HttpKernel.php:78)
  at Symfony\Component\HttpKernel\HttpKernel->handle()
     (vendor/symfony/http-kernel/Kernel.php:199)
  at Symfony\Component\HttpKernel\Kernel->handle()
     (public/index.php:20)

TypeError:
Proxies\__CG__\App\Entity\Structure::setName(): Argument #1 ($name) must be of type string, null given, called in /***/vendor/symfony/property-access/PropertyAccessor.php on line 576

  at var/cache/dev/doctrine/orm/Proxies/__CG__AppEntityStructure.php:251
  at Proxies\__CG__\App\Entity\Structure->setName()
     (vendor/symfony/property-access/PropertyAccessor.php:576)
  at Symfony\Component\PropertyAccess\PropertyAccessor->writeProperty()
     (vendor/symfony/property-access/PropertyAccessor.php:175)
  at Symfony\Component\PropertyAccess\PropertyAccessor->setValue()
     (vendor/symfony/form/Extension/Core/DataAccessor/PropertyPathAccessor.php:68)
  at Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor->setValue()
     (vendor/symfony/form/Extension/Core/DataAccessor/ChainAccessor.php:54)
  at Symfony\Component\Form\Extension\Core\DataAccessor\ChainAccessor->setValue()
     (vendor/symfony/form/Extension/Core/DataMapper/DataMapper.php:87)
  at Symfony\Component\Form\Extension\Core\DataMapper\DataMapper->mapFormsToData()
     (vendor/symfony/form/Form.php:640)
  at Symfony\Component\Form\Form->submit()
     (vendor/symfony/form/Extension/HttpFoundation/HttpFoundationRequestHandler.php:109)
  at Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler->handleRequest()
     (vendor/symfony/form/Form.php:501)
  at Symfony\Component\Form\Form->handleRequest()
     (src/Controller/StructureController.php:36)
  at App\Controller\StructureController->edit()
     (vendor/symfony/http-kernel/HttpKernel.php:156)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw()
     (vendor/symfony/http-kernel/HttpKernel.php:78)
  at Symfony\Component\HttpKernel\HttpKernel->handle()
     (vendor/symfony/http-kernel/Kernel.php:199)
  at Symfony\Component\HttpKernel\Kernel->handle()
     (public/index.php:20)   

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions