bluebird@3.5.1: MongoDB mongoose@4.13.7 Promises library

> Warning: a promise was created in a handler 
> at internal/process/next_tick.js:180:9 but was not returned from it, 
> see
>    at model.Query.ret [as execAsync] 
> (eval at makeNodePromisifiedEval
>   (/home/bike/github/, <anonymous>:8:21)

mongoose Promises : bluebird

Built-in Promises

Mongoose async operations, like .save() and queries, return Promises/A+ conformant promises. This means that you can do things like MyModel.findOne({}).then() and yield MyModel.findOne({}).exec() (if you’re using co).

For backwards compatibility, Mongoose 4 returns mpromise promises by default.

Queries are not promises

Mongoose queries are not promises.
However, they do have a .then() function for yield and async/await.
If you need a fully-fledged promise, use the .exec() function.

    var query = Band.findOne({name: "Guns N' Roses"});
    assert.ok(!(query instanceof require('mpromise')));

    // A query is not a fully-fledged promise, but it does have a `.then()`.
    query.then(function (doc) {
      // use doc

    // `.exec()` gives you a fully-fledged promise
    var promise = query.exec();
    assert.ok(promise instanceof require('mpromise'));

    promise.then(function (doc) {
      // use doc

Plugging in your own Promises Library

New in Mongoose 4.1.0

While mpromise is sufficient for basic use cases, advanced users may want to plug in their favorite [ES6-style promises library]( like [bluebird](, or just use native ES6 promises.
Just set mongoose.Promise to your favorite ES6-style promise constructor and mongoose will use it.

Mongoose tests with ES6 native promises, [bluebird](, and [q](

    var query = Band.findOne({name: "Guns N' Roses"});

    // Use native promises
    mongoose.Promise = global.Promise;
    assert.equal(query.exec().constructor, global.Promise);

    // Use bluebird
    mongoose.Promise = require('bluebird');
    assert.equal(query.exec().constructor, require('bluebird'));

    // Use q. Note that you **must** use `require('q').Promise`.
    mongoose.Promise = require('q').Promise;
    assert.ok(query.exec() instanceof require('q').makePromise);

Promises for the MongoDB Driver

The mongoose.Promise property sets the promises mongoose uses.
However, this does not affect the underlying MongoDB driver.

If you use the underlying driver, for instance Model.collection.db.insert(),
you need to do a little extra work to change the underlying promises library.
Note that the below code assumes mongoose >= 4.4.4.

    var uri = 'mongodb://localhost:27017/mongoose_test';

    // Use bluebird
    var options = { promiseLibrary: require('bluebird') };

    var db = mongoose.createConnection(uri, options);

    Band = db.model('band-promises', { name: String });

    db.on('open', function() {
      assert.equal(Band.collection.findOne().constructor, require('bluebird'));


server/app.js file:

 . . .
import config from './config/environment';
import http from 'http';
import mailer from './config/mailer';

import bluebird from 'bluebird';
import mongoose from 'mongoose';

// Use `bluebird` as default Promise Library
mongoose.Promise = bluebird;

// Connect to MongoDB
//console.log('>> mongo.options: '+ JSON.stringify(config.mongo.options))
mongoose.connect(config.mongo.uri, config.mongo.options);
mongoose.connection.on('error', function(err) {
  console.error('MongoDB connection error: ' + err);

server/config/environment/index.js file:

'use strict';
  . . .
  // MongoDB connection options
  // <>
  // - `promiseLibrary` [object]: A Promise library class the application wishes to use such as Bluebird, must be ES6 compatible
  // - `appname`    [string]: The name of the application that created this MongoClient instance.
  // - `loggerLevel` [string]: The logging level (error/warn/info/debug)
  // - `logger` [object]: Custom logger object
  // Plugging in your own Promises Library
  // New in Mongoose 4.1.0
  // <>
  mongo: {
    options: {
      useMongoClient: true,
      promiseLibrary: require('bluebird'), // Use `bluebird` as default Promise Library
      loggerLevel: 'debug',
      validateOptions: true
   . . .

server/api/user/user.model.js file:

import {Schema} from 'mongoose';
import {Promise} from 'bluebird';

var mongoose = Promise.promisifyAll(require('mongoose'));

// Use `bluebird` as default Promise Library
mongoose.Promise = Promise;
 . . .

server/api/user/user.controller.js file:

Change findById(), findByIdAndRemove() to

  • User.findByIdAndRemoveAsync().then(…)
  • User.findByIdAsync().then(…)
 * Get a single user
export function show(req, res, next) {
  var userId =;

    .then(user => {
      if (!user) {
        return res.status(404).end();
      return res.json(user.profile);
    .catch(err => next(err));

 * Deletes a user
 * restriction: 'admin'
export function destroy(req, res) {
    .then(function() {
      return res.status(204).end();
. . .

Leave a Reply