symfony: Calling handleRequest() after setData() on a form may cause unhandled exceptions

Q A
Bug report? yes
Feature request? no
BC Break report? ?
RFC? no
Symfony version 4.0.3

I have a form configured as a service, and reused from the controller. When I try to update an existing entity with empty submitted data, an unhandled Exception is thrown, because the form attempts to set object’s property to null, even though both object and the form itself require that property to be a non-empty string. Here’s the relevant method:

    public function edit(Request $request, Customer $customer): Response
    {
        $this->form->setData($customer);
        $this->form->handleRequest($request); //  <-----THIS FAILS!

        if ($this->form->isSubmitted() && $this->form->isValid()) {
            $this->entityManager->flush();

            $this->addFlash('success', 'Customer updated successfully.');

            return $this->redirectToRoute('customer.show', ['id' => $customer->getId()]);
        }

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

This looks like a bug to me. If it isn’t, any pointers to how my code should be fixed would be appreciated.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 20 (10 by maintainers)

Most upvoted comments

I guess registering your form like that is possible, but I wouldn’t recommend it. This will give every form where it’s injected, the same instance, rather than a unique and isolated instance. It also prevents you from properly binding your data.

Besides of that, could it be that your field is empty? It seems like you want strictness (entity is my guess), but you’re using your entity as a form object if I see it correctly. This conflicts, you can’t have a valid entity because the form forces it to be invalid at a given point:

    public function edit(Request $request, Customer $customer): Response
    {
        $this->form_factory->create(CustomerType::class, $customer/*, $options*/);
        $this->form->handleRequest($request);

        if ($this->form->isSubmitted() && $this->form->isValid()) {
            $this->entityManager->flush();

            $this->addFlash('success', 'Customer updated successfully.');

            return $this->redirectToRoute('customer.show', ['id' => $customer->getId()]);
        }

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