Skip to content

Latest commit

 

History

History
106 lines (78 loc) · 3.6 KB

README.md

File metadata and controls

106 lines (78 loc) · 3.6 KB

JavaScript Style Guide Coverage Status CI node-current Downloads

Express Rescue

This is a dependency-free wrapper (or sugar code layer if you will) for async middlewares which makes sure all async errors are passed to your stack of error handlers, allowing you to have a cleaner and more readable code.

Note Even though this library is supposed to work on node >= 7.6, we are unable to test against node versions 7, 8 and 9 because our tooling requires at least node version 10. We'll keep the minimum requirement for this library at version node >= 7.6 so that we allow old projects to keep getting updates, but be aware that we are unable to test againt the mentioned versions.

How to use it

It's really simple:

const rescue = require('express-rescue')

/**
 * `rescue` insures thrown errors are passed to `next` callback.
 */
app.get('/:id', rescue(async (req, res, next) => {
    const user = await repository.getById(req.params.id)

    if (!user) {
      throw new UserNotFoundError
    }

    res.status(200)
       .json(user)
}))

/**
 * `rescue.from` allows you to handle a specific error which is helpful for
 * handling domain errors.
 */
app.use(rescue.from(UserNotFoundError, (err, req, res, next) => {
    res.status(404)
       .json({ error: 'these are not the droids you\'re looking for'})
})

/**
 * Your error handlers still works as expected. If an error doesn't match your
 * `rescue.from` criteria, it will find its way to the next error handler.
 */
app.use((err, req, res, next) => {
    res.status(500)
       .json({ error: 'i have a bad feeling about this'})
})

There's a helper function rescue.all([...]) in case you want to wrap several functions with rescue. With rescue.all, doing [rescue(fn1), rescue(fn2)] can be shortened to rescue.all([fn1, fn2]).

const rescue = require('express-rescue')

// Doing it like this
app.post('/products', rescue.all([
    validationFn,
    createProductFn
]))

// Is equivalent to this
app.post('/products', [
    rescue(validationFn),
    rescue(createProductFn)
])

That's all.

Hope you enjoy the async/await heaven!

Chears!

Tests

> express-rescue@1.2.0 test
> mocha test/*.test.js --check-leaks --full-trace --use_strict --recursive

  const callable = rescue(async ([err,] req, res, next) => { })
    calls the last argument (next) with the thrown error
      ✔ All arguments are been passed to the callback
      ✔ Raises a TypeError if last argument is not a function
      ✔ callable(req, res, next) - works for routes and middlewares
      ✔ callable(err, req, res, next) - works for error handler middlewares
      ✔ callable(foo, bar, baz, foobar, foobaz, errorHandler) - should work for
        basically anything, as long as your function takes an error handler as
        the last parameter

  rescue.from(MyError, (err) => { })
    ✔ handles the error when error is instance of given constructor
    ✔ it call `next` function if error is not an instance of given constructor

  const callables = rescue.all([fn1, fn2, fn3])
    ✔ All given functions are wrapped with rescue

  8 passing (8ms)