How to tell if a <script> tag failed to load

Solution 1:

There is no error event for the script tag. You can tell when it is successful, and assume that it has not loaded after a timeout:

<script type="text/javascript" onload="loaded=1" src="....js"></script>

Solution 2:

UPDATE 2021: All browsers today support onerror="" on script tags, examples:

  • Building script tag in js on MDN
  • Html example by @Rudey in comments: <script src="nonexistent.js" onerror="alert('error!')"></script>

Original comment from 2010:

If you only care about html5 browsers you can use error event.

From the spec:

If the src attribute's value is the empty string or if it could not be resolved, then the user agent must queue a task to fire a simple event named error at the element, and abort these steps.

(...)

If the load resulted in an error (for example a DNS error, or an HTTP 404 error) Executing the script block must just consist of firing a simple event named error at the element.

This means you don't have to do any error prone polling and can combine it with async and defer attribute to make sure the script is not blocking page rendering:

The defer attribute may be specified even if the async attribute is specified, to cause legacy Web browsers that only support defer (and not async) to fall back to the defer behavior instead of the synchronous blocking behavior that is the default.

More on http://www.w3.org/TR/html5/scripting-1.html#script

Solution 3:

my working clean solution (2017)

function loaderScript(scriptUrl){
   return new Promise(function (res, rej) {
    let script = document.createElement('script');
    script.src = scriptUrl;
    script.type = 'text/javascript';
    script.onError = rej;
    script.async = true;
    script.onload = res;
    script.addEventListener('error',rej);
    script.addEventListener('load',res);
    document.head.appendChild(script);
 })

}

As Martin pointed, used like that:

const event = loaderScript("myscript.js")
  .then(() => { console.log("loaded"); })
  .catch(() => { console.log("error"); });

OR

try{
 await loaderScript("myscript.js")
 console.log("loaded"); 
}catch{
 console.log("error");
}