|
1 |
| -# ExpressJS Async Errors |
| 1 | +# @csnw/express-async-errors |
2 | 2 |
|
3 |
| -[](https://travis-ci.org/davidbanham/express-async-errors) |
| 3 | +An async/await patch for [Express](https://expressjs.com/) error handlers. Async functions already work fine in Express, this module improves support for thrown errors. |
4 | 4 |
|
5 |
| -A dead simple ES6 async/await support hack for [ExpressJS](http://expressjs.com) |
| 5 | +This package is compatible with both ESM and CommonJS projects. It additionally differs from [express-async-errors](https://www.npmjs.com/package/express-async-errors) by expecting the patch function be called explicitly instead of when the module is `require`'d. |
6 | 6 |
|
7 |
| -Shamelessly copied from [express-yields](https://github.com/MadRabbit/express-yields) |
| 7 | +This is a fork of a fork; thank you to the original authors: |
8 | 8 |
|
9 |
| -This has been lightly reworked to handle async rather than generators. |
| 9 | +- [MadRabbit/express-yields](https://github.com/MadRabbit/express-yields) |
| 10 | +- [davidbanham/express-async-errors](https://github.com/davidbanham/express-async-errors) |
10 | 11 |
|
11 | 12 | ## Usage
|
12 | 13 |
|
| 14 | +```sh |
| 15 | +npm install @csnw/express-async-errors --save |
13 | 16 | ```
|
14 |
| -npm install express-async-errors --save |
15 |
| -``` |
16 |
| - |
17 |
| -Then require this script somewhere __before__ you start using it: |
18 | 17 |
|
19 |
| -Async functions already work fine in Express. |
| 18 | +Run the patch before building `express()`. For example: |
20 | 19 |
|
21 | 20 | ```js
|
22 |
| -const express = require('express'); |
23 |
| -require('express-async-errors'); |
24 |
| -const User = require('./models/user'); |
25 |
| -const app = express(); |
26 |
| - |
27 |
| -app.get('/users', async (req, res) => { |
28 |
| - const users = await User.findAll(); |
29 |
| - res.send(users); |
30 |
| -}); |
31 |
| -``` |
32 |
| - |
33 |
| -This library is about what happens when you hit an error. |
| 21 | +import express from 'express'; |
| 22 | +import expressAsyncErrors from '@csnw/express-async-errors'; |
34 | 23 |
|
35 |
| -## A Notice About Calling `next` |
36 |
| - |
37 |
| -As we all know express sends a function called `next` into the middleware, which |
38 |
| -then needs to be called with or without error to make it move the request handling |
39 |
| -to the next middleware. It still works, but in case of an async function, you |
40 |
| -don't need to do that. If you want to pass an error, just throw a normal exception: |
41 |
| - |
42 |
| -```js |
43 |
| -app.use(async (req, res) => { |
44 |
| - const user = await User.findByToken(req.get('authorization')); |
| 24 | +// Apply patch and then build express |
| 25 | +expressAsyncErrors(); |
| 26 | +const app = express(); |
45 | 27 |
|
46 |
| - if (!user) throw Error("access denied"); |
| 28 | +app.get('/version', async (req, res) => { |
| 29 | + const version = parseInt(req.query.v); |
| 30 | + if (isNaN(version)) { |
| 31 | + // Throw error from async request handler |
| 32 | + throw new Error('version should be a number'); |
| 33 | + } |
| 34 | + res.status(200).json({ version }); |
47 | 35 | });
|
48 | 36 |
|
| 37 | +// Request error handler receives the thrown error |
49 | 38 | app.use((err, req, res, next) => {
|
50 |
| - if (err.message === 'access denied') { |
51 |
| - res.status(403); |
52 |
| - res.json({ error: err.message }); |
| 39 | + if (err.message === 'version should be a number') { |
| 40 | + res.status(400).json({ error: err.message }); |
| 41 | + return; |
53 | 42 | }
|
| 43 | + res.status(500).json({ error: 'unexpected error' }); |
| 44 | +}); |
54 | 45 |
|
55 |
| - next(err); |
| 46 | +app.listen(3000, () => { |
| 47 | + console.info('Server running at http://localhost:3000'); |
56 | 48 | });
|
57 | 49 | ```
|
58 | 50 |
|
59 | 51 | ## How Does This Work?
|
60 | 52 |
|
61 |
| -This is a very minimalistic and unintrusive hack. Instead of patching all methods |
62 |
| -on an express `Router`, it wraps the `Layer#handle` property in one place, leaving |
63 |
| -all the rest of the express guts intact. |
64 |
| - |
65 |
| -The idea is that you require the patch once and then use the `'express'` lib the |
66 |
| -usual way in the rest of your application. |
| 53 | +This is a minimalistic and unintrusive hack. Instead of patching all methods on an express `Router`, it wraps the `Layer#handle` property in one place, leaving all the rest of express as-is. Apply the patch once and then freely throw errors from all your async request handlers! |
67 | 54 |
|
68 | 55 | ## License
|
69 | 56 |
|
|
0 commit comments