Skip to content

Instantly share code, notes, and snippets.

@spion
Last active May 19, 2016 00:50
Show Gist options
  • Save spion/13cdfbf0fee3ad3b7bed5c469f9d4045 to your computer and use it in GitHub Desktop.
Save spion/13cdfbf0fee3ad3b7bed5c469f9d4045 to your computer and use it in GitHub Desktop.

Real domains post mortem.

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.

image

Of course its not going to work. It changes the contract that everyone else is relying on.

Why promises don't have the problem.

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.

@trevnorris
Copy link

I'm missing what this contributes and/or corrects with the existing domain postmortem.

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.

No one disagrees that domain.enter() (or domains all together) were a bad idea. But what Promises have to do with the domain postmortem is unclear.

@Fishrock123
Copy link

Fishrock123 commented May 13, 2016

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

@spion
Copy link
Author

spion commented May 19, 2016

@trevnorris Nothing really, it just tries to show how domains are not really the same with Promises.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment