Invoke a function expecting an error to be thrown.
If an error is not thrown, call `cb` with an error and return a rejected Promise.
@param {Function} fn function to execute within a try/catch
@param {RegExp|String|Function|Error} matcher to match error against
@param {Function} [cb] callback to invoke on success
@returns {Promise} returns resolved Promise on success
@throws Error when `fn` does not throw or error does not satisfy `matcher`
function catchAndMatch(fn, matcher, cb) {
    return isIllegalArguments({ fn: fn, matcher: matcher, cb: cb }).then(fn, function (err) {
      throw err;
    }).then(function () {
      // If we got here the function did not throw an error
      var error = new Error('No error thrown');
      if (cb) cb(error);
      return Promise.reject(error);
    }, function (err) {
      // Error was thrown - check that it satisfies the matcher
      if (doesMatch({ matcher: matcher, err: err })) {
        if (cb) cb();
        return Promise.resolve();
      }
      var error = new Error('Error does not satisfy matcher');
      if (cb) cb(error);
      return Promise.reject(error);
    });
  }