Verified Commit e492ae34 authored by Lauri Timmanee's avatar Lauri Timmanee
Browse files

Issue #2987444 by hooroomoo, lauriii, bnjmnm, alwaysworking, tim.plunkett,...

Issue #2987444 by hooroomoo, lauriii, bnjmnm, alwaysworking, tim.plunkett, smustgrave, ckrina, Gábor Hojtsy: Ajax errors are not communicated through the UI
parent 9a527be3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -374,6 +374,7 @@ drupal.ajax:
    - core/once
    - core/tabbable
    - core/loadjs
    - core/drupal.message

drupal.announce:
  version: VERSION
+12 −0
Original line number Diff line number Diff line
@@ -179,6 +179,18 @@
     * @type {string}
     */
    this.name = 'AjaxError';

    if (!Drupal.AjaxError.messages) {
      Drupal.AjaxError.messages = new Drupal.Message();
    }
    Drupal.AjaxError.messages.add(
      Drupal.t(
        "Oops, something went wrong. Check your browser's developer console for more details.",
      ),
      {
        type: 'error',
      },
    );
  };

  Drupal.AjaxError.prototype = new Error();
+14 −0
Original line number Diff line number Diff line
@@ -115,3 +115,17 @@ ajax_test.global_events_clear_log:
    _controller: '\Drupal\ajax_test\Controller\AjaxTestController::globalEventsClearLog'
  requirements:
    _access: 'TRUE'

ajax_test.exception_link:
  path: '/ajax-test/exception-link'
  defaults:
    _controller: '\Drupal\ajax_test\Controller\AjaxTestController::exceptionLink'
  requirements:
    _access: 'TRUE'

ajax_test.throw_exception:
  path: '/ajax-test/throw-exception'
  defaults:
    _controller: '\Drupal\ajax_test\Controller\AjaxTestController::throwException'
  requirements:
    _access: 'TRUE'
+32 −0
Original line number Diff line number Diff line
@@ -387,4 +387,36 @@ public function globalEventsClearLog() {
    return $response;
  }

  /**
   * Callback to provide an exception via Ajax.
   *
   * @throws \Exception
   *   The expected exception.
   */
  public function throwException() {
    throw new \Exception('This is an exception.');
  }

  /**
   * Provides an Ajax link for the exception.
   *
   * @return array
   *   The Ajax link.
   */
  public function exceptionLink() {
    return [
      '#type' => 'link',
      '#url' => Url::fromRoute('ajax_test.throw_exception'),
      '#title' => 'Ajax Exception',
      '#attributes' => [
        'class' => ['use-ajax'],
      ],
      '#attached' => [
        'library' => [
          'core/drupal.ajax',
        ],
      ],
    ];
  }

}
+40 −0
Original line number Diff line number Diff line
@@ -251,4 +251,44 @@ protected function assertWaitPageContains(string $expected): void {
    }), "Page contains expected value: $expected");
  }

  /**
   * Tests that Ajax errors are visible in the UI.
   */
  public function testUiAjaxException() {
    $themes = [
      'olivero',
      'claro',
      'stark',
    ];
    \Drupal::service('theme_installer')->install($themes);

    foreach ($themes as $theme) {
      $theme_config = \Drupal::configFactory()->getEditable('system.theme');
      $theme_config->set('default', $theme);
      $theme_config->save();
      \Drupal::service('router.builder')->rebuildIfNeeded();

      $this->drupalGet('ajax-test/exception-link');
      $page = $this->getSession()->getPage();
      // We don't want the test to error out because of an expected Javascript
      // console error.
      $this->failOnJavascriptConsoleErrors = FALSE;
      // Click on the AJAX link.
      $this->clickLink('Ajax Exception');
      $this->assertSession()
        ->statusMessageContainsAfterWait("Oops, something went wrong. Check your browser's developer console for more details.", 'error');

      if ($theme === 'olivero') {
        // Check that the message can be closed.
        $this->click('.messages__close');
        $this->assertTrue($page->find('css', '.messages--error')
          ->hasClass('hidden'));
      }
    }

    // This is needed to avoid an unfinished AJAX request error from tearDown()
    // because this test intentionally does not complete all AJAX requests.
    $this->getSession()->executeScript("delete window.jQuery");
  }

}
Loading