I have some Javascript code doing some asyncronous stuff with some synchronouse post processing and then asyncronous stuff again (XHR -> parse XHR -> new XHR based on the first one). I don't get the error handling done:
/* API */
function getFile(name) {
return $.ajax({
url: name + ".json"
}).then(function(data) {
return data.id
}, handleError)
}
function handleError(errorObj) {
if (errorObj.status) {
return errorObj.status
} else {
return errorObj
}
}
function myApiCall() {
return getFile(1)
.then(getFile, handleError)
.then(getFile, handleError)
.then(getFile, handleError)
.then(getFile, handleError);
}
/* caller */
function failFunction(status) {
console.log("fail: ")
console.log(status)
}
myApiCall().then(function(id) {
console.log(id)
}, failFunction)
1.json
looks something like this
{
"id": "2"
}
Just referencing the next file, the other ones are equivalent.
Until here everything is fine (even I'm not sure if that's the best way to do errorhandling). If all files exist, the success function of the caller is called, otherwise the error function.
But when having some errors in my synchronous code, everthing breaks
function getFile(name) {
return $.ajax({
url: name + ".json"
}).then(function(data) {
throw new Error(42) // <---------
}, handleError)
}
Now I get a console output
Error: 42
No further processing, caller is not informed.
I tried something like that
function getFile(name) {
return $.ajax({
url: name + ".json"
}).then(function(data) {
throw new Error(42)
}, handleError)
.catch(handleError)
}
But this doesn't make anything better. Mostly of all I get a TypeError: $.ajax(...).then(...).catch is not a function
How is error handling solved correct in this case?
Because you are handling errors at every stage, and not propagating them, then you will end up with the problems you are having
edit:
The above statement is wrong, I didn't realise how broken jquery promises are when I wrote it - see the difference between the first block of code (Promise/A+) and the second (jQuery promise with fingers crossed behind it's back)
instead you can do something like:
function getFile(name) {
// wrap jquery "promise" in real Promise
// you'll need a Promise polyfill for Internet Explorer to use this method
return new Promise(function(resolve, reject) {
$.ajax({
url: name + ".json?" + Math.random()
}).then(function(data) {
resolve(data.id);
}, function(err) {
reject(err);
});
});
}
function handleError(errorObj) {
//console.log(errorObj)
if (errorObj.status) {
throw errorObj.status;
} else {
throw errorObj;
}
}
function myApiCall() {
return getFile(1)
.then(getFile)
.then(getFile)
.then(getFile)
.then(getFile)
.catch(handleError);
}
function failFunction(status) {
console.log("fail: ")
console.log(status)
}
myApiCall().then(function(id) {
console.log(id);
})
.catch(failFunction);
When using jQuery, whose promises are like promises you make with your fingers crossed behind your back
function getFile(name) {
return $.ajax({
url: name + ".json"
}).then(function(data) {
return data.id;
});
}
function handleError(errorObj) {
if (errorObj.status) {
return errorObj.status; // return in jquery!
} else {
return errorObj;
}
}
function myApiCall() {
return getFile(1)
.then(getFile)
.then(getFile)
.then(getFile)
.then(getFile)
.fail(handleError); // like jquery promises in general, use fail instead of the compliant catch
}
/* caller */
function failFunction(status) {
console.log("fail: ");
console.log(status);
}
myApiCall().then(function(id) {
console.log(id);
})
.fail(failFunction);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With