Search code examples
javascripthtmlecmascript-6promiseunhandled-promise-rejection

Why does "unhandledrejection" event not fire from the file:// protocol?


Consider the following example:

var prom1 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    console.log("Promise executed");
    reject("Rejected");
  }, 2000);
});

console.log("Before Promise");
var test = prom1.then(function(data) {
    console.log(data, 1);  
    return data;
  }); //skipping onReject handeler

window.addEventListener("unhandledrejection", function() {
  console.log("unhandledrejection");  
});

In this case unhandledrejection fired, because we skipped the onReject handler in the then function. So far, everything as expected. Now let's consider another example, where I completly omit the then handler.

var prom2 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    console.log("Promise executed");
    reject("Rejected");
  }, 2000);
});

console.log("Before Promise2");

//skipping onReject handeler, because we skip the whole "then" method.

window.addEventListener("unhandledrejection", function() {
  console.log("unhandledrejection");  
});

Now both the scripts give same output, but if you save this code in html file and open without a server(no localhost), e.g. as file:///C:/Users/test/index.html you will see that unhandledrejection didn't execute this time. Why is that?

P.S: I have tested on my windows 10 Chrome Version 107.0.5304.88 (Official Build) (64-bit), Firefox version 106.0.5 (64 bit), Edge Version 107.0.1418.35 (Official build) (64-bit) and Opera latest version.

P.S2: As aksed in the comments, I have added the whole html file. I had no idea that in file:// protocol my own javascript files are considerd cross origin:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>  
        <script src="js/script.js"></script>
    </body>
</html>

Solution

  • This is because your external script is considered "cross-origin" when loaded from the file:// protocol.
    This will cause its internal muted errors property to be set to true.

    When a classic script with its muted errors attribute set to true is to track a Promise rejection, it will early exit, without firing the unhandledrejection event.

    This is to prevent other scripts on the page to be able to read the content of this script through the event's details.