Catch asynchronous network error from XMLHttpRequest send()
Solution 1
Use the onerror
event of the XMLHttpRequest
:
function aGet(url, cb) {
var x = new XMLHttpRequest();
x.onload = function(e) {
cb(x.responseText)
};
x.onerror= function(e) {
alert("Error fetching " + url);
};
x.open("GET", url, true);
x.send();
}
var dmp = console.log.bind(console); // Dummy callback to dump to console
aGet("/", dmp) // Ok, uses onload to trigger callback
aGet("http://dgfgdf.com/sdfsdf", dmp); // Fails, uses onerror to trigger alert
Solution 2
I wrote a full solution to that problem. It works perfectly!
I have a function called networkOrfail
which will try to resend the XMLHttpRequest
each second, if the network is available. Otherwise, it'll ignore the request.
When the request is succeeded, that polling stops and the response is returned.
Here's how to detect whether the network is available:
function getNavigatorConection() {
return navigator.onLine;
}
Then, create your XMLHttpRequest
:
function makeRequest() {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'anypage/anotherpage', true);
xhr.timeout = 2000;
xhr.onload = function () {
// Your request is completed
if (xhr.readyState == 4 && xhr.status == 200) {
// You're in a successfully condition
}
};
xhr.ontimeout = function (e) {
// Your request timed out
};
xhr.send(null);
}
Now, define your polling method as follows:
function networkOrFail(callFunc, callTime) {
let connected = getNavigatorConection();
let callableTimes = callTime < 2000 ? 2000 : callTime;
let toursBegin = 3;
let tours = toursBegin;
let intervalId;
let request = function() {
intervalId = setInterval(function() {
let connected = getNavigatorConection();
if (tours > 0) {
if (connected) {
callFunc();
tours =0;
return false;
}
tours--;
alert("i tryied againt to resend for another time and it remain just "+tours+" to retry");
} else {
clearRequest();
tours =toursBegin;
}
}, callableTimes > 5000 ? 5000 : callableTimes);
};
let clearRequest = function() {
clearInterval(intervalId);
intervalId = null;
};
if (connected)
callFunc();
else
request();
}
Finally, call the send method through the polling method by passing it toghether with the timeout in minutes:
networkOrFail(makeRequest, 5000);
rustybeanstalk
Updated on July 24, 2022Comments
-
rustybeanstalk almost 2 years
I'm making an http request asynchronously using
XMLHttpRequest
:xhr.open(method, uri, true);
When I send
something
:xhr.send(something)
When the server is down, it throws the following error:
net::ERR_CONNECTION_REFUSED
How can I catch and handle this error? The standard
try..catch
block doesn't work as the request is asynchronous.Thanks in advance.
-
rustybeanstalk over 9 yearsI was under the impression that this is only supported Chrome, Safari & Firefox, but not in Opera or various mobile browsers. Do you know what the support is for onerror? Thanks.
-
dandavis over 9 yearslooks pretty solid: caniuse.com/#feat=xhr2, plus msdn.microsoft.com/en-us/library/ie/cc288060(v=vs.85).aspx you'll have to roll the two into one to hit 95%, but that's vanilla for ya!
-
generalchaos over 9 yearsThis is not working for me. I am trying to make a PUT request and when the server returns an error, neither xhr.onerror or xhr.upload.error handlers are catching the error. Having the error propagate to the browser is causing other javascript issues.
-
Tengiz over 8 yearsstill throws a nasty error in the console. Any way to prevent that?