This PR adds support for catching errors from rejected promises (perhaps in the
form of an async function) that matches the existing try/catch behavior for
synchronous returning functions.
[Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
have now been part of the JavaScript specification for over a year and are
popularly used for modeling asynchronous behavior (such as rendering a webpage).
They're even mentioned in an express [article about best practices](https://expressjs.com/en/advanced/best-practice-performance.html#use-promises).
However one of the pitfalls of using Promises is being aware of error
behavior and not forgetting to call `.catch()`. This is a prominent note in that
same article. However a common behavior is to "chain" Promises and allow for the
top-most Promise to handle the error. For libraries where error-handling is
critical, like webservers or test harnesses, being Promise-aware and allowing
functions to return Promises can help isolate error behavior from the library
user. Mocha is a [great example of this done well](http://paulsalaets.com/testing-with-promises-in-mocha). Users of Express may inadvertently expect this
behavior, return a Promise from their routing functions, and then be surprised
when errors are swallowed during debugging.
Support for Promises will become more critical as [Async functions](https://tc39.github.io/ecmascript-asyncawait/) enters the language, giving first-class
language syntax for creating and operating on promises. This proposal is
expected to be ratified soon, is already implemented in Chakra-node, is
implemented behind a flag in Chrome, is expected to arrive in node v7, and is
already used by many via transpilers like Babel. This makes proper error
handling for Promises imminent as this use case is about to become far
more common.
Example of code where Express error handling will work just fine:
```js
app.get('/', (req, res) => {
throw new Error('Oh crap!')
})
```
And a minor syntax modification leads to swallowed errors:
```js
app.get('/', async (req, res) => {
throw new Error('Oh crap!')
})
```
This PR approaches a solution to the problem as minimally-invasive as possible.
It does not presume anything about the host environment, and it detects and
supports the [Promise A](http://wiki.commonjs.org/wiki/Promises/A) subset of the
Promise specification, which many older Promise libraries only support.