Javascript promise error handling

I have Javascript code that does some asynchronous things with some sort of synchronous mail processing and then again asynchronous (XHR -> parsing XHR -> new XHR based on the first). I do not do error handling:

/* 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 refers to the following file, others are equivalent.

So far, everything is fine here (even I'm not sure if this is the best way to do error handling). If all files exist, the caller's success function is called; otherwise, the error function.

But if there are 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 console output

 Error: 42 

No further processing, the caller is not informed.

I tried something like this

 function getFile(name) { return $.ajax({ url: name + ".json" }).then(function(data) { throw new Error(42) }, handleError) .catch(handleError) } 

But it does nothing better. Basically I get TypeError: $.ajax(...).then(...).catch is not a function

How is error handling correct in this case?

+5
source share
2 answers

Since you handle errors at every stage and do not redistribute them, then you will encounter problems that you encounter

edit:

The above statement is wrong, I did not understand how broken jquery promises when I wrote it - see the difference between the first block of code (Promise / A +) and the second (jQuery promise with fingers crossed back to 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 similar to promises, you do with 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); 
+8
source

All of you are tired of promises when using jQuery. promises are real cool; jQuery promises suck. Here's another example code based on Jaromandas that answers everyone who can use it.

 /* API */ function getFileWithError(name) { return getFile(name, true) } function getFile(name, doThrow) { if (name == null) { console.log("handled null as return from chain before") name = 2 } return wrapJquery( $.ajax({ url: name + ".json?" + Math.random() }) ).then(function(data) { if (data.id == 2) { return null } if (doThrow) { throw data.id } return data.id }); } function wrapJquery(crossingFingersPromise) { return new Promise(function(resolve, reject) { crossingFingersPromise .then(function(data) { resolve(data); }, function(err) { reject(err); }); }) } function handleError(errorObj) { if (errorObj.status) { throw errorObj.status; // return in jquery! } else { throw errorObj; } } function myApiCall() { return getFile(1) .then(getFile) .then(getFileWithError) .then(getFile, function(error) { console.log("recovering from error") return getFile(error) }) .then(getFile) .catch(handleError) } /* caller */ function failFunction(status) { console.log("fail: "); console.log(status); } myApiCall().then(function(id) { console.log(id); }) .catch(failFunction); 
0
source

Source: https://habr.com/ru/post/1236993/


All Articles