In the beginning there were callbacks.
But JS also had exceptions.
The combination of both was not working becuase catch only caught sync stuff.
try {
doAsync(something, function(err, res) {
// try is useless in here.
});
} catch (err) {
}
Instead of solving this, we gave up on it and said whatever, we wont use exceptions.
Once we decided this, it was just so convenient to ignore exceptions and let the process crash, that became our default solution.
Also to make things even more complicated, we didn't really decide we wont use exceptions. Instead we came up with this muddied distinction between programmer errors and operational errors and bullshitted everyone that throw
= programmer errors and callback(err)
= operational errors.
Now our contract is to not catch thrown errors. Async thrown errors crash the process. There is no need to clean things up.
Then we realized wait, this doesn't work. Mostly because of the muddying above being somewhat. wrong.
So we came up with an ad-hoc solution to catch errors, called domains.
With no thought to what a safe API for those might be. So domain.enter()
is fine.
Of course its not going to work. It changes the contract that everyone else is relying on.
First of all, promises don't change the contract of existing code.
If you are using callbacks, all of your async callback code stays under old contract.
Secondly, for the sync part there are two options:
(1) Promisify using promisifier that catches errors
This looks dangerous, but in practice most modules don't do stupid things like:
internalState.doSomethingUnrecoverable()
doSomethingThatThrowsSync();
doAsyncStuff(function(err) {
// ...
})
Most of the dangerous stuff are async.
Still, if you don't feel comfortable with that, you can
(2) Use a crashy promisify wrapper.
and you're done.
For posterity to anyone who sees this, here is the domains postmortem doc as found in the Node.js source code: https://github.com/nodejs/node/blob/master/doc/topics/domain-postmortem.md