#322·co

Promises still in the event Loop

Author: ernie58Created Nov 16, 2017Updated Nov 16, 2017

I'm having a problem with unit tests in mocha, while testing a function that uses co. Since Mocha 4 tests don't exit automatically anymore when things are still 'hanging' in the event loop. (server connections, unresolved promises, etc...)

Below is a simple test file, notice the after hook, which dumps things that are still in the event loop: The test doesn't exit while it should! When I take the Error out of the generator function, it works as expected, but in my real use case that's not what I want.

Under the code you can see 3 Promises that are still pending after running the tesr (logged to console)

node
'use strict';

const co = require('co');

/** sample class for testing **/
class myTest {
    static doStuff(name){
        return co(function* coStart() {
            if (name !== 'john') {
              throw new Error('invalid data, wrong name');
            }
            //further more I do some async stuff
            let ret = yield Promise.resolve('good');
            return  ret;
        });
    }
}

/** mocha test **/
describe('test', function () {
    const assert = require('assert');

    after(function () {
        global.asyncDump();
      });

    describe('doStuff', function () {
        it('should reject when using a name thats not john', function (done) {
            myTest.doStuff('bert')
                .then(() => done('it should fail'))
                .catch(function(err){
                    assert.equal(err.message, 'invalid data, wrong name');
                    done();
            });
        });
    });
});

logs:

STUFF STILL IN THE EVENT LOOP:
Type: SIGNALWRAP
Error
    at AsyncHook.init (async-dump.js:12:62)
    at Signal.emitInitNative (async_hooks.js:472:43)
    at process.<anonymous> (internal/process.js:204:20)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3


Type: PROMISE
Error
    at AsyncHook.init (async-dump.js:12:62)
    at PromiseWrap.emitInitNative (async_hooks.js:472:43)
    at new Promise (<anonymous>)
    at co (node_modules/co/index.js:50:10)
    at Function.doStuff (server/tests/unit/test.js:7:16)
    at Context.<anonymous> (server/tests/unit/test.js:27:20)


Type: PROMISE
Error
    at AsyncHook.init (async-dump.js:12:62)
    at PromiseWrap.emitInitNative (async_hooks.js:472:43)
    at Promise.then (<anonymous>)
    at Context.<anonymous> (server/tests/unit/test.js:28:18)


Type: PROMISE
Error
    at AsyncHook.init (async-dump.js:12:62)
    at PromiseWrap.emitInitNative (async_hooks.js:472:43)
    at Promise.catch (<anonymous>)
    at Context.<anonymous> (server/tests/unit/test.js:29:23)


Type: Immediate
Error
    at AsyncHook.init (async-dump.js:12:62)
    at emitInitNative (async_hooks.js:472:43)
    at emitInitScript (async_hooks.js:388:3)

Im running the test with this command:

./node_modules/mocha/bin/_mocha --require async-dump server/tests/unit/test.js -R spec

The async-dump-script I require is from this gist: https://gist.github.com/subfuzion/54a9413d02c6d9ba223076bebd49e38f

Is this considered a bug (that can cause memory issues)?

I've tried with Promise.reject instead of throwing errors, and also yield Promise.reject, but that doesn't help either.

I'm aware that mocha has an --exit flag to exit anyway, but it's considered bad practice, I want to make sure nothing keeps hanging.

My node version is v8.9.1

Thx in advance