The anti-pattern mentioned by @JaromandaX is forcing you to unnecessarily jump through flaming hoops to accommodate it... and your getting burned.
But, first, you are rejecting to the outer (redundant) promise from the then before the catch so the catch is by-passed.  After an error is thrown in a promise chain, the first thenable with a second argument (onRejected) will consume it: so it won't be propagated beyond that.  But, anyway, you need to trap the error on the outer promise which you are rejecting.
this.createUser = function (data) {
  var query = "INSERT into users SET ?";
  return new Promise((resolve, reject) => {  //   the first 'then' rejects to here
    Container.DB.query(query, data)          //   broken promise: anti-pattern
      .then((response) => {
        console.log("Resolved", response);
        return resolve(response);
      }, (error) => {
        console.log("REJECTION ERROR", error);//<--the error is consumed here and will
                                              //   not go any further on this chain
        return reject('An unknown error occurred and has been reported.');
      })
      .catch((err) => {                       //   this will not be called
        console.log("CAUGHT ERROR", err);     //   because it is the 'onRejected'
                                              //   argument of a then
      });
  })
    .catch((err) => {   // this will be called and the error will be consumed
      console.log("CAUGHT ERROR", err);
      return 'An unknown error occurred and has been reported.';
    });
  ;
}
Less worse, you can log and re-throw the error in one catch...
this.createUser = function (data) {
  var query = "INSERT into users SET ?";
  return new Promise((resolve, reject) => {  // this is still redundant
    Container.DB.query(query, data)          // broken promise: anti-pattern
      .then((response) => {                  // on error, skip this because it has no
        console.log("Resolved", response);   // 'onRejected' argument
        return resolve(response);
      })
      .catch((err) => {                      // this will be called and the error
        console.log("CAUGHT ERROR", err);    // will be consumed
        return reject('An unknown error occurred and has been reported.');
      });
  })
    ;
}
Better, eliminate the anti-pattern and propagate the message with a throw instead of a reject on the (redundant) promise wrapper...
this.createUser = function (data) {
  var query = "INSERT into users SET ?";
  return Container.DB.query(query, data)
    .then((response) => {                  // on error, skip this because it has no
      console.log("Resolved", response);   // 'onRejected' argument
      return resolve(response);
    })
    .catch((err) => {                      // this will be called and the error
      console.log("CAUGHT ERROR", err);    // will be consumed so need to re-throw
      throw new Error('An unknown error occurred and has been reported.');
    });
}
Bearing in mind that a catch is just syntactic sugar for then(undefined, reject) and that, once rejected, a promise is no longer pending, calling it's then method will return undefined 'as soon as possible'.  So you can chain another then after the catch if you prefer not to throw...
this.createUser = function (data) {
  var query = "INSERT into users SET ?";
  return Container.DB.query(query, data)
    .then((response) => {                  // on error, skip this because it has no
      console.log("Resolved", response);   // 'onRejected' argument
      return resolve(response);
    })
    .catch((err) => {                      // this will be called and the error
      console.log("CAUGHT ERROR", err);    // will be consumed. The returned promise
    })                                     // state will be rejected but not pending
                                           // It's then method returns 'undefined' as 
                                           // soon as possible
    .then(() => 'An unknown error occurred and has been reported.');
}
Taking it one step further, bearing in mind that the value returned by a resolved or rejected promise is the return value of whichever of those is called, you can pass any value you like to the consumer via the return in the catch...
this.createUser = function (data) {
  var query = "INSERT into users SET ?";
  return Container.DB.query(query, data)
    .then((response) => {                  // on error, skip this because it has no
      console.log("Resolved", response);   // 'onRejected' argument
      return resolve(response);
    })
    .catch((err) => {                      // this will be called and the error
      console.log("CAUGHT ERROR", err);    // will be consumed. The returned promise
                                           // state will be rejected but not pending
                                           // but you can still return any value
      return 'An unknown error occurred and has been reported.'
    })
}