Building on a previous answer and an attempt to write a comprehensive XMLHttpRequest
example that covers all kinds of possible errors and return them to caller gracefully instead of a crash.
function Remote() {}
Remote.upload = function(formData, progressHandler) {
return new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:3000");
xhr.setRequestHeader("Accept", "application/json");
xhr.addEventListener("error", function(event){
reject({code: 0, message: "A network error occurred.", event: event});
});
xhr.upload.addEventListener("progress", progressHandler);
xhr.addEventListener("readystatechange", function() {
if(xhr.readyState == 4 && xhr.status != 0) { // exclude status 0
try {
xhr.status == 200 ? resolve(JSON.parse(xhr.response)) : reject(JSON.parse(xhr.response));
} catch(error) {
reject({code: 0, message: "JSON parsing error.", body: xhr.response});
}
}
});
xhr.send(formData);
});
};
function progressHandler(event) {
if(event.lengthComputable) {
console.log((event.loaded / event.total * 100 | 0));
}
}
Here in this example, I've added a check in the readystatechange
not to handle status 0 errors since event handler can be triggered with all sorts of those errors, whether invalid certificate, offline or request getting suppressed. (Limitation: Can't figure out the exact error scenario hence the generic Network error message.
- 200 status is success as suggested by the REST contract so it's hard coded.
- JSON parsing error is also a possibility to handle any issues.
- Code is meant to be backward compatible for older browsers.
Hope the code is comprehensive and takes care of all corners.