Skip to content

Instantly share code, notes, and snippets.

@alanshaw
Last active September 16, 2016 14:15
Show Gist options
  • Save alanshaw/e66dacdd637bbac18dcff45c24be3187 to your computer and use it in GitHub Desktop.
Save alanshaw/e66dacdd637bbac18dcff45c24be3187 to your computer and use it in GitHub Desktop.

The problem:

// This is used as express middleware
// Express middleware should look like: `function (req, res, next)`

const wrap = require('watt').wrap

// Firstly, super confusing because `next` in the code below is actually watt's `next`, not express `next`
// Express calls this with (req, res, expressNext) - I've renamed next to `expressNext` to diffentiate
// Watt chops `expressNext` from the args and passes just req and res to the generator
// Why does it do this?
// It rightly thinks `expressNext` is a callback that should be called when this function is completed
module.exports = wrap(function* (req, res, next) {
  // So, say we have some async op that could throw:
  try {
    yield somethingAsyncThrows(next)
  } catch (err) {
    return res.error(500, err)
    // `res.error` is a function attached to `res` by some previous middleware
    // It does this:
    // ```js
    // function (code, err) {
    //   console.log(code, error)
    //   this.status(code).json({ error: err.message })
    //   return err
    // }
    // ```
  }
})

What happens now? What you'd think might happen is:

We catch the error and return from the generator, no further code is executed, request completes and the server returns HTTP 500 with some error message JSON payload.

No!

When this function returns, watt calls expressNext(null, ret), where ret is whatever is returned from the function. Which in this case is an error object.

We're kinda doing this cb(null, err) - which is bad news!

Consequently it actually doesn't halt the middleware chain or pass control to error middleware.

If we wanted to halt the middleware, we'd need to throw res.error(500, err) to get watt to call expressNext(err).

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