Skip to content

[LiveComponent] BatchActionController does not properly handle redirection response #1300

Closed
@6insanes

Description

@6insanes

Hi!

This is a bug report. Bug relates to BatchActionController and LiveComponentSubscriber::onKernelResponse.

I have simple LiveComponent class UserForm with ComponentWithFormTrait and submit LiveAction which looks like this:

#[LiveAction]
public function submit(EntityManagerInterface $defaultEntityManager): Response
{
    $this->submitForm();
    $defaultEntityManager->flush();

    return $this->redirectToRoute('app_user_index');
}

On the web page we have submit button with data-action="live#action" and data-action-name='prevent|submit' attributes. When changing form data and hitting submit button quickly multiple times I got 500 LogicException from /_components/UserForm/_batch

LogicException:
The submitForm() method is being called, but the FormView has already been built. Are you calling $this->getForm() - which creates the FormView - before submitting the form?

  at vendor/symfony/ux-live-component/src/ComponentWithFormTrait.php:151
  at App\Twig\Components\UserForm->submitForm()
     (src/Twig/Components/UserForm.php:36)
  at App\Twig\Components\UserForm->submit(object(EntityManagerGhostEbeb667))
     (vendor/symfony/http-kernel/HttpKernel.php:181)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 2)
     (vendor/symfony/http-kernel/HttpKernel.php:76)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 2, false)
     (vendor/symfony/ux-live-component/src/Controller/BatchActionController.php:43)
  at Symfony\UX\LiveComponent\Controller\BatchActionController->__invoke(object(Request), object(MountedComponent), 'App\\Twig\\Components\\UserForm', array(array('name' => 'submit', 'args' => array()), array('name' => 'submit', 'args' => array())))
     (vendor/symfony/http-kernel/HttpKernel.php:181)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (vendor/symfony/http-kernel/HttpKernel.php:76)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor/symfony/http-kernel/Kernel.php:197)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php:35)
  at Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner->run()
     (vendor/autoload_runtime.php:29)
  at require_once('/app/vendor/autoload_runtime.php')
     (public/index.php:5)                

I think this happens because in BatchActionController condition on line 45 $response->isRedirection() is never true and loop continues and action is executed multiple times even if LiveAction returns redirection response. Loop continues because LiveComponentSubscriber::onKernelResponse interferes and changes subrequests http response code to Response::HTTP_NO_CONTENT which is 204 and Response::isRedirection method checks for >= 300 and < 400.

Possible solution is to add to LiveComponentSubscriber::onKernelResponse check for $event->isMainRequest() because changing response http code and adding REDIRECT_HEADER makes sense only for main request.

php: 8.1
symfony: 6.3
symfony-ux: 2.13.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions