Javascript: How can I lint for promise chains that do not have a `fail` block at the end?

1k views Asked by At

How can I lint my Javascript code to identify promise chains (promise.then().then().then()...) that do not have a fail block at the end? Do any of the existing tools (JSHint, JSLint, the Flow static type checker, Typescript, ...?) allow this?

The motivation for this, candidly, is that sometimes I just forget to put one in code that I write. Then, if an error occurs in that code, it will fail silently and it can be a beast to debug. Instead, it would be better software engineering to be able to catch those errors at lint-time in the same way that I can use linting to identify typos in variable names

For example:

q(this_function_returns_a_promise())
.then(function(data) {
  console.log('The promise returned some data: ' + JSON.stringify(data));
})
// .. more thens, spreads, alls
.then(function(modified_data) {
  this_function_will_throw_an_error(modified_data);
})
// .. more thens, spreads, alls
.then(function(modified_modified_data) {
  console.log('I will not be printed, logging and execution will just stop in ' +
    'the middle then()');
});
// if only there was a .fail(function(err) { ... }) here that printed the error!
1

There are 1 answers

1
AudioBubble On BEST ANSWER

This is not something you can lint for or otherwise identify via static analysis. There are many (most?) cases where a promise chain does not provide a catch and doesn't need to or want to, because the catch will happen somewhere downstream.

What you need to do is use your promise library's facilities for reporting on "zombie" promises, or uncaught rejected promises. This will happen at run-time, not "compile" time. The specifics of how to do that will differ from library to library. Some browsers are already beginning to implement things along this line. In Chrome, try typing the following into the console:

> Promise.resolve().then(function() {throw "throw";})
< Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
< Uncaught (in promise) throw
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^