2

I am coding a native JavaScript application in which I make simultaneous AJAX requests to multiple unique servers every minute. When a server is offline, I intended my program to handle this through the function registered to the XHR.ontimeout event.

Below is a quick JS sample I wrote to demonstrate my problem. Monitor the console and you will see only sometimes requests to an offline address trigger the ontimeout event. Other times ERR_CONNECTION_TIMED_OUT occurs. I would like to have a timeout handler that executes every time I call my function and the server is offline.

<!DOCTYPE html>
<html>
<TITLE>Timeout Error Demo</TITLE> 
<body>
<script>
var i=0;
var xhr;
function main(){
   console.log('Main run #'+i);
   i++;
   xhr=new XMLHttpRequest();
   xhr.open("GET", "http://1.1.1.1", true);   //this address is always offline
   xhr.timeout=2000;
   xhr.ontimeout=function(){
      console.log("timed out");
   }
   xhr.onreadystatechange=function(){
      if (xhr.readyState==4 && xhr.status==200){
         console.log("done");
      }
   }
   xhr.send(null);
   setTimeout(main,5000);
}
main();
</script>
</body>
</html>
Power Duck
  • 33
  • 2
  • 8

2 Answers2

1

It's .ontimeout, not .onTimeout. Or .addEventListener("timeout", …).

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

As i see it the core of the problem here is that you misunderstand how the ontimeout event works. So i will try to explain how the browser works with ontimeout and what the difference is with onerror.

ontimeout

The ontimeout event will to thrown when a request is made to the server and that request get succesfully through to the server. Then if the server takes a long time to response the timeout event will get thrown by the HTTPRequest. Ex:

Client side

    xhr.timeout = 2000;
    xhr.send();
    xhr.open("GET", /somecontroller/IAmAReallySlowEndpoint, true);
    xhr.ontimeout = function() {
        console.log("I get called because the server was to slow to response on a succesfull request");
    }

Server side endpoint (C#)

public bool IAmAReallySlowEndpoint() 
{
  Thread.Sleep(4000);
  return true;
}

you call a server side endpoint which does not answer within 2 seconds then the ontimeout event will get thrown.

onerror The onerror event will throw if an error in the http request happens which is the case in your example. You want to call an url that is down. Calling an url that is down will throw an error and thereby the onerror event is called.

So when you write that it works when do you:

xhr.ontimeout = xhr.onerror

You are just passing the onerror event to the ontimeout.

So to solve your problem with doing stuff if one of the endpoints you are requesting is down you should implement some retry logic kinda like you already have with a setTimeout() but deciding if the server is down or not should be based on numbers of failed request to the server instead of the ontimeout.

Poku
  • 3,138
  • 10
  • 46
  • 64
  • I have the spelling correct in my actual program and it still behaves as described. I will edit original post to correct the mistake. – Power Duck May 11 '17 at 21:56
  • I see. I changed my answer. Your code will throw an error not a timeout. – Poku May 11 '17 at 22:15
  • So when my server goes down and its url no longer exists, it throws an error instead of a timeout? And in the meantime before the browser has realized this url does not exist, it triggers the xhr.ontimeout event? I would like to understand why ontimeout occurs sometimes, and other times the error is thrown. See the edit to my original question for a clear example. – Power Duck May 11 '17 at 22:18
  • I set `xhr.onerror=xhr.ontimeout` so that my handler function is executed every time. However if someone has some insight into why the error is thrown sometimes and the ontimeout event is triggered other times, I would greatly appreciate it. – Power Duck May 12 '17 at 16:51
  • I do not know why the ontimeout event triggers sometimes and the error is thrown other times. By setting `xhr.onerror=xhr.ontimeout` I have a band-aid solution so that my timeout function executes every time. – Power Duck May 16 '17 at 17:54
  • @PowerDuck i rewrote my answer to explain how the ontimeout works in the browser. I hope this will help you understand the problem :) – Poku May 18 '17 at 05:56