Catch 'uncaughtException' error in your mocha test

Catch 'uncaughtException' error in your mocha test

By David WORMS

Oct 27, 2013

Categories: Node.js | Tags: DevOps, JavaScript, Mocha, Unit tests

This isn’t the first time I faced this situation. Today, I finally found the time and energy to look for a solution. In your mocha test, let’s say you need to test an expected “uncaughtException” event, the Node.js technique to catch the uncatchable. Easy, just register an “uncaughtException” listener to the process event emitter. Well, not so easy, but not so complicate either.

Let’s start with a simple test:

describe 'uncaughtException', ->
  it 'should be tested', (next) ->
    try
      process.nextTick ->
        idontexist()
    catch e
      console.error 'Never called'

Install mocha with npm install mocha, save the file as ‘test.coffee’ and run mocha --compilers coffee:coffee-script test.coffee. As you can see, the error isn’t caught by your code, only mocha get a hold of it.

So the obvious starting point is to register an “uncaughtException” event listener, part of the native Node.js “process” module. That gives us:

describe 'uncaughtException', ->
  it 'should be tested', (next) ->
    process.on 'uncaughtException', (err) ->
      console.error 'idontexist is not defined'
      next()
    try
      process.nextTick ->
        idontexist()
    catch e
      console.error 'Never called'

As you can notice, we are grabbing the error and we are able to call the “next” callback. However, Mocha gets into our legs and does not let us handle that error gracefully. It reports that error as an error, even if we were happy about it. What an intrusive behavior, but let’s not blame Mocha, it is required for other situations.

What can we do about it? We unplug the mocha listener, and any other listener if there are any, plug ours and, when we’re done, re-wire everything the way it was, not forgetting to unplug our just created listener. Hope I was clear. This is the final code:

describe 'uncaughtException', ->
  it 'should be tested', (next) ->
    lsts = process.listeners 'uncaughtException'
    process.removeAllListeners 'uncaughtException'
    process.on 'uncaughtException', (err) ->
      console.error 'idontexist is not defined'
      process.removeAllListeners 'uncaughtException'
      for lst in lsts
        process.on 'uncaughtException', lst
      next()
    try
      process.nextTick ->
        idontexist()
    catch e
      console.error 'Never called'

You can view it in action in the just published error test part of the each iterator module.

UPDATE: The links in the article might be broken.

Canada - Morocco - France

International locations

10 rue de la Kasbah
2393 Rabbat
Canada

We are a team of Open Source enthusiasts doing consulting in Big Data, Cloud, DevOps, Data Engineering, Data Science…

We provide our customers with accurate insights on how to leverage technologies to convert their use cases to projects in production, how to reduce their costs and increase the time to market.

If you enjoy reading our publications and have an interest in what we do, contact us and we will be thrilled to cooperate with you.