Search code examples
javascriptdomerror-handling

Web page self-detecting external elements failing to load


I would like to detect in a web page when some of its javascript or css elements have failed to load, and alert the user. I have the below but it does not work.

(The actual use-case involves end-users needing certain certificates installed and if elements fail to load, the page will give them instructions on how to update their browser/OS. But this is a minimum reproducible testcase on my way to that solution.)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="x-ua-compatible" content="ie=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <title>Lorum Title Ipsus</title>

    <script>
      
      document.addEventListener('DOMContentLoaded', (event) => {
        // Monitor <script> elements
        document.querySelectorAll('script[src]').forEach(script => {
            script.addEventListener('error', function() {
            alert('Failed to load script:', script.src);
          }, true);
        });
    
        // Monitor <link rel="stylesheet"> elements
        document.querySelectorAll('link[rel="stylesheet"]').forEach(link => {
            link.addEventListener('error', function() {
            alert('Failed to load stylesheet:', link.href);
          }, true);
        });

      });
      </script>
    <!-- **** NOTE THE OBVIOUS ERROR BELOW -->
    <link href="https://ERRRORcdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
  </head>

  <body>
    Lorum Ipsus
  </body>
</html>

Solution

  • For synchronous scripts, the DOMContentLoaded event will fire only after they have been (attempted to be) loaded and evaluated, so you're missing the error event.

    You could try a mutation observer to detect the creation of the scripts and immediately attach your error handlers, or try to attach your error event handlers on the window or document or document.head itself (although it should not bubble).