title: Can't set headers after they are sent : multiple middleware executions concurency
body: <p>In my main express.js config file, I <code>use</code> two custom error middleware functions:</p>
  
  <pre><code>const error = require('../middlewares/error');
  
  // catch 404 and forward to error handler
  app.use(error.notFound);
  
  // if error is not an instanceOf APIError, convert it.
  app.use(error.converter);
  </code></pre>
  
  <p>I use <a href="https://www.npmjs.com/package/boom" rel="nofollow noreferrer">boom</a> to unify error messages. this is my error middleware:</p>
  
  <pre><code>module.exports = {
    /**
     * Error responder. Send stacktrace only during development
     * @public
     */
    responder: (err, req, res, next) =&gt; {
      res.status(err.output.payload.statusCode);
      res.json(err.output.payload);
      res.end();
    },
  
    /**
     * If error is not a Boom error, convert it.
     * @public
     */
    converter: (err, req, res, next) =&gt; {
      if (env !== 'development') {
        delete err.stack;
      }
      if (err.isBoom) {
        return module.exports.responder(err, req, res);
      }
      if (err.name === 'MongoError' &amp;&amp; err.code === 11000) {
        const boomedError = boom.conflict('This email already exists');
        boomedError.output.payload.stack = err ? err.stack : undefined;
        return module.exports.responder(boomedError, req, res);
      }
      const boomedError = boom.boomify(err, { statusCode: 422 });
      return module.exports.responder(boomedError, req, res);
    },
  
    /**
     * Catch 404 and forward to error responder
     * @public
     */
    notFound: (req, res) =&gt; {
      const err = boom.notFound('Not Found');
      return module.exports.responder(err, req, res);
    },
  };
  </code></pre>
  
  <p>My problem is, when I make a "register" action with an existing email, the <code>responder()</code> is executed three times. One for my boom.conflict error, but then also one for "not found". (even though I've done <code>res.end()</code>.</p>
  
  <p>This is the register logic:</p>
  
  <pre><code>exports.register = async (req, res, next) =&gt; {
    try {
      validationResult(req).throw();
      const user = new User(req.body);
      const token = generateTokenResponse(user, user.token());
      const userTransformed = user.transform();
      user.tokens.push({ kind: 'jwt', token });
      user.activationId = uuidv1();
      await user.save();
      res.status(httpStatus.CREATED);
      sendValidationEmail(user.activationId);
      return res.json({ user: userTransformed });
    } catch (err) {
      return next(converter(err, req, res, next));
    }
  };
  </code></pre>
  
  <p><code>user.save()</code> triggers this by the way:</p>
  
  <pre><code>userSchema.pre('save', async function save(next) {
    try {
      if (!this.isModified('password')) return next();
  
      const rounds = env === 'test' ? 1 : 10;
  
      const hash = await bcrypt.hash(this.password, rounds);
      this.password = hash;
  
      return next();
    } catch (err) {
      return next(converter(err));
    }
  });
  </code></pre>