You are here

public function FormAjaxSubscriber::onException in Drupal 9

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php \Drupal\Core\Form\EventSubscriber\FormAjaxSubscriber::onException()

Catches a form AJAX exception and build a response from it.

Parameters

\Symfony\Component\HttpKernel\Event\ExceptionEvent $event: The event to process.

File

core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php, line 82

Class

FormAjaxSubscriber
Wraps AJAX form submissions that are triggered via an exception.

Namespace

Drupal\Core\Form\EventSubscriber

Code

public function onException(ExceptionEvent $event) {
  $exception = $event
    ->getThrowable();
  $request = $event
    ->getRequest();

  // Render a nice error message in case we have a file upload which exceeds
  // the configured upload limit.
  if ($exception instanceof BrokenPostRequestException && $request->query
    ->has(FormBuilderInterface::AJAX_FORM_REQUEST)) {
    $this->messenger
      ->addError($this
      ->t('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@size) that this server supports.', [
      '@size' => $this
        ->formatSize($exception
        ->getSize()),
    ]));
    $response = new AjaxResponse(NULL, 200);
    $status_messages = [
      '#type' => 'status_messages',
    ];
    $response
      ->addCommand(new PrependCommand(NULL, $status_messages));
    $event
      ->allowCustomResponseCode();
    $event
      ->setResponse($response);
    return;
  }

  // Extract the form AJAX exception (it may have been passed to another
  // exception before reaching here).
  if ($exception = $this
    ->getFormAjaxException($exception)) {
    $request = $event
      ->getRequest();
    $form = $exception
      ->getForm();
    $form_state = $exception
      ->getFormState();

    // Set the build ID from the request as the old build ID on the form.
    $form['#build_id_old'] = $request->request
      ->get('form_build_id');
    try {
      $response = $this->formAjaxResponseBuilder
        ->buildResponse($request, $form, $form_state, []);

      // Since this response is being set in place of an exception, explicitly
      // mark this as a 200 status.
      $response
        ->setStatusCode(200);
      $event
        ->allowCustomResponseCode();
      $event
        ->setResponse($response);
    } catch (\Exception $e) {

      // Otherwise, replace the existing exception with the new one.
      $event
        ->setThrowable($e);
    }
  }
}