One problem with JavaScript promises

Forget this and yours debugging will be harder

The promises are great. I love them. Their usage simplifies the task of managing a bunch of asynchronous tasks. The simplicity is in switching the context to future and encapsulating all it into an object. This gives new expressiveness to the code.

There’s one problem with promises. They make it much harder to see if you missed any error handling.

With traditional Node.js way you have an error as the first argument to the callback:

const fs = require('fs');

fs.stat('/etc/passwd', (err, stats) => {
  if (err) {
    console.error(err);
  }
  // ... do something
});

It’s obvious from just reading the code that you ignored the error. With the right tool (eslint for example) that fact will be singled out.

The following code uses a promise but ignores the error looks fine and no simple tool will complain about it:

const fsp = require('fs-promise');

fsp.stat('/etc/passwd').then(stat => {
  // ... do something
});

Of course the correct way would be:

const fsp = require('fs-promise');

fsp.stat('/etc/passwd')
.then(stat => {
  // ... do something
})
.catch(console.error);

It requires a bit of extra self-discipline. Working with promises is less intuitive than it should be. It requires more mental effort to remember to handle all those errors. Node solves this problem in a simple and beautiful way. Just put error as the first argument. That way it’s almost impossible to miss it.

I’m not the first one pointing this out. Pretty much every guide or tutorial about promises talks about this common mistake.

It’s one thing to just read about something and another when things don’t work as you would expect. When struggling with a program is not working although there’s no clue why not.

That’s one of the advantages of direct experience with any technology. You ingrain those common mistakes into your practice. They will become the problem of a past.