简体   繁体   中英

Do promises in AngularJS catch every exception/error?

I've inherited a codebase at work that contains a dozen or so examples of the following pattern:

var promise = null;
try {
    promise = backendService.getResults(input);
}
catch (exception) {
    console.err(exception);
}
if (promise !== null) {
    promise.then(function (response) {
        // do stuff
    })
    .catch(function (error) {
        console.err(error);
    });
}

Where backendService is an Angular service that in turn calls a REST service through $http .

So here's my question: is that try/catch really necessary? Will there ever be any scenario where a particular error/exception is thrown that the promise's .catch fails to catch?

This has been the subject of a bit of debate on the team all morning, and the only resolution we've come up with is that we don't think it's necessary, but (a) changing it breaks the tests that were written alongside it (which would also need to be changed), and (b) well... it's defensive coding, right? It's not a Bad Thing.

The merits of actually bothering to refactor it into oblivion when there are more important things to do aren't what I'm asking about, though. I just want to know if it's a reasonable pattern when promises are being passed around like this (in AngularJS specifically, if that makes a difference), or just paranoia.

Do promises in AngularJS catch every exception/error?

No. Only exceptions that are thrown from inside then / catch callbacks are automatically caught. All errors happening outside of them will need to be handled explicitly.

Will there ever be any scenario where a particular error/exception is thrown that the promise's .catch fails to catch?

Yes. That backendService.getResults(input) call might not return a promise, but it can throw an exception. Or it doesn't even get that far when backendService is null, and you'll get a ReferenceError or .getResults is not a function and you'll get a TypeError .

is that try/catch really necessary?

Not really. In the latter case, that your code has a grave mistake, you probably don't care to throw and crash. The former case, that backendService.getResults(input) throws, is heavily despised. Asynchronous functions should never throw but only return promises - exactly for the reason that you don't have to write two error handling statements then.

well... it's defensive coding, right? It's not a Bad Thing.

Yeah, pretty much. But it is questionable here. A synchronous exceptions is really unexpected here, not just a service whose failure can be handled. The logging message in the catch block should signify that.

Notice that it also isn't defensive enough. It doesn't catch the probably more likely mistake where getResults() does return, but something that is not a promise. Calling .then() on that might throw. Similarly, the if (promise !== null) is dubious, as it hides when null is returned erroneously (we really could need try-catch-else here).

is that try/catch really necessary?

Not really. As long as your backendService.getResults() returns a promise. Like return $http(...)

Will there ever be any scenario where a particular error/exception is thrown that the promise's .catch fails to catch?

I don't think so, since any error will be a rejected promise, it will fall into your .catch() handler

well... it's defensive coding, right? It's not a Bad Thing.

It depends... Javascript try/catch is has some performance issues. So if you're using just for the sake of making sure, you could remove it :)

Take a further look at try-catch discussion here if you wish: Javascript Try-Catch Performance Vs. Error Checking Code

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM