diff --git a/core/modules/system/tests/modules/js_errors_test/js/js_errors_async_test.js b/core/modules/system/tests/modules/js_errors_test/js/js_errors_async_test.js
new file mode 100644
index 0000000000..5270836810
--- /dev/null
+++ b/core/modules/system/tests/modules/js_errors_test/js/js_errors_async_test.js
@@ -0,0 +1,11 @@
+/**
+ * @file
+ *  Test script for JavaScript errors thrown in async context.
+ */
+(function () {
+  addEventListener("DOMContentLoaded", () => {
+    setTimeout(() => {
+      throw new Error('An error thrown in async context.');
+    });
+  });
+})();
diff --git a/core/modules/system/tests/modules/js_errors_test/js_errors_test.libraries.yml b/core/modules/system/tests/modules/js_errors_test/js_errors_test.libraries.yml
index 3454e7cb63..3e7f12748b 100644
--- a/core/modules/system/tests/modules/js_errors_test/js_errors_test.libraries.yml
+++ b/core/modules/system/tests/modules/js_errors_test/js_errors_test.libraries.yml
@@ -4,3 +4,9 @@ errors_test:
     js/js_errors_test.js: {}
   dependencies:
     - core/drupal
+errors_async_test:
+  version: VERSION
+  js:
+    js/js_errors_async_test.js: {}
+  dependencies:
+    - core/drupal
diff --git a/core/modules/system/tests/modules/js_errors_test/js_errors_test.routing.yml b/core/modules/system/tests/modules/js_errors_test/js_errors_test.routing.yml
index d096284e25..c25e8c500f 100644
--- a/core/modules/system/tests/modules/js_errors_test/js_errors_test.routing.yml
+++ b/core/modules/system/tests/modules/js_errors_test/js_errors_test.routing.yml
@@ -5,3 +5,10 @@ js_errors_test.errors:
     _title: 'JsErrorsTest'
   requirements:
     _access: 'TRUE'
+js_errors_async_test.errors:
+  path: '/js_errors_async_test'
+  defaults:
+    _controller: '\Drupal\js_errors_test\Controller\JsErrorsTestController::jsErrorsAsyncTest'
+    _title: 'JsErrorsAsyncTest'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/js_errors_test/src/Controller/JsErrorsTestController.php b/core/modules/system/tests/modules/js_errors_test/src/Controller/JsErrorsTestController.php
index 99628a272c..817fa395b4 100644
--- a/core/modules/system/tests/modules/js_errors_test/src/Controller/JsErrorsTestController.php
+++ b/core/modules/system/tests/modules/js_errors_test/src/Controller/JsErrorsTestController.php
@@ -19,4 +19,16 @@ public function jsErrorsTest(): array {
     ];
   }
 
+  /**
+   * Renders page that has js_errors_test/errors_async_test library attached.
+   *
+   * @return string[][]
+   *   Render array.
+   */
+  public function jsErrorsAsyncTest(): array {
+    return [
+      '#attached' => ['library' => ['js_errors_test/errors_async_test']],
+    ];
+  }
+
 }
diff --git a/core/modules/system/tests/modules/js_testing_log_test/js/js_testing_log.js b/core/modules/system/tests/modules/js_testing_log_test/js/js_testing_log.js
index dd6fe578ed..7cf146eb27 100644
--- a/core/modules/system/tests/modules/js_testing_log_test/js/js_testing_log.js
+++ b/core/modules/system/tests/modules/js_testing_log_test/js/js_testing_log.js
@@ -2,7 +2,7 @@
  * @file
  *  Support code for testing JavaScript error handling in functional tests.
  */
-(function (Drupal) {
+(function () {
   if (typeof console !== 'undefined' && console.warn) {
     const originalWarnFunction = console.warn;
     console.warn = (warning) => {
@@ -17,19 +17,17 @@
       );
       originalWarnFunction(warning);
     };
-
-    const originalThrowFunction = Drupal.throwError;
-    Drupal.throwError = (error) => {
-      const errors = JSON.parse(
-        sessionStorage.getItem('js_testing_log_test.errors') ||
-          JSON.stringify([]),
-      );
-      errors.push(error.stack);
-      sessionStorage.setItem(
-        'js_testing_log_test.errors',
-        JSON.stringify(errors),
-      );
-      originalThrowFunction(error);
-    };
   }
-})(Drupal);
+
+  addEventListener("error", (evt) => {
+    const errors = JSON.parse(
+      sessionStorage.getItem('js_testing_log_test.errors') ||
+        JSON.stringify([]),
+    );
+    errors.push(evt.error.stack);
+    sessionStorage.setItem(
+      'js_testing_log_test.errors',
+      JSON.stringify(errors),
+    );
+  });
+})();
diff --git a/core/modules/system/tests/modules/js_testing_log_test/js_testing_log_test.libraries.yml b/core/modules/system/tests/modules/js_testing_log_test/js_testing_log_test.libraries.yml
index d02c19893c..0ca138a76c 100644
--- a/core/modules/system/tests/modules/js_testing_log_test/js_testing_log_test.libraries.yml
+++ b/core/modules/system/tests/modules/js_testing_log_test/js_testing_log_test.libraries.yml
@@ -2,5 +2,4 @@ deprecation_log:
   version: VERSION
   js:
     js/js_testing_log.js: {}
-  dependencies:
-    - core/drupal
+  dependencies: []
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/JavascriptErrorsTest.php b/core/tests/Drupal/FunctionalJavascriptTests/JavascriptErrorsTest.php
index a62657b0eb..372f7b7820 100644
--- a/core/tests/Drupal/FunctionalJavascriptTests/JavascriptErrorsTest.php
+++ b/core/tests/Drupal/FunctionalJavascriptTests/JavascriptErrorsTest.php
@@ -39,6 +39,21 @@ public function testJavascriptErrors(): void {
     $this->failOnJavaScriptErrors();
   }
 
+  public function testJavascriptErrorsAsync(): void {
+    // Visit page that will throw a JavaScript console error in async context.
+    $this->drupalGet('js_errors_async_test');
+    // Ensure that errors from previous page loads will be
+    // detected.
+    $this->drupalGet('user');
+
+    $this->expectException(AssertionFailedError::class);
+    $this->expectExceptionMessageMatches('/^Error: An error thrown in async context./');
+
+    // Manually call the method under test, as it cannot be caught by PHPUnit
+    // when triggered from assertPostConditions().
+    $this->failOnJavaScriptErrors();
+  }
+
   /**
    * Clear the JavaScript error log to prevent this test failing for real.
    *
