Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding documentation around using promises in middleware #1134

Merged
merged 1 commit into from
Apr 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions en/guide/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,27 @@ app.get('/', function (req, res, next) {
})
```

If you pass anything to the `next()` function (except the string `'route'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions.
Starting with Express 5, route handlers and middleware that return a Promise
will call `next(value)` automatically when they reject or throw an error.
For example:

If the callback in a sequence provides no data, only errors, you can simplify this code as follows:
```js
app.get('/user/:id', async function (req, res, next) {
var user = await getUserById(req.params.id)
res.send(user)
})
```

If `getUserById` throws an error or rejects, `next` will be called with either
the thrown error or the rejected value. If no rejected value is provided, `next`
will be called with a default Error object provided by the Express router.

If you pass anything to the `next()` function (except the string `'route'`),
Express regards the current request as being an error and will skip any
remaining non-error handling routing and middleware functions.

If the callback in a sequence provides no data, only errors, you can simplify
this code as follows:

```js
app.get('/', [
Expand Down
55 changes: 52 additions & 3 deletions en/guide/writing-middleware.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ The following figure shows the elements of a middleware function call:
</td></tr>
</table>

Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error.

<h2>Example</h2>

Here is an example of a simple "Hello World" Express application.
The remainder of this article will define and add two middleware functions to the application:
one called `myLogger` that prints a simple log message and another called `requestTime` that
displays the timestamp of the HTTP request.
The remainder of this article will define and add three middleware functions to the application:
one called `myLogger` that prints a simple log message, one called `requestTime` that
displays the timestamp of the HTTP request, and one called `validateCookies` that validates incoming cookies.

```js
var express = require('express')
Expand Down Expand Up @@ -140,6 +142,53 @@ app.listen(3000)

When you make a request to the root of the app, the app now displays the timestamp of your request in the browser.

<h3>Middleware function validateCookies</h3>

Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid.

Here's an example function that validates cookies with an external async service.

```js
async function cookieValidator (cookies) {
try {
await externallyValidateCookie(cookies.testCookie)
} catch {
throw new Error('Invalid cookies')
}
}
```

Here we use the [`cookie-parser`](/resources/middleware/cookie-parser.html) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler.

```js
var express = require('express')
var cookieParser = require('cookie-parser')
var cookieValidator = require('./cookieValidator')

var app = express()

async function validateCookies (req, res, next) {
await cookieValidator(req.cookies)
next()
}

app.use(cookieParser)

app.use(validateCookies)

// error handler
app.use(function (err, req, res, next) {
res.status(400).send(err.message)
})

app.listen(3000)

```

<div class="doc-box doc-notice" markdown="1">
Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions.
</div>

Because you have access to the request object, the response object, the next middleware function in the stack, and the whole Node.js API, the possibilities with middleware functions are endless.

For more information about Express middleware, see: [Using Express middleware](/{{ page.lang }}/guide/using-middleware.html).
Expand Down