Skip to content

Instantly share code, notes, and snippets.

@benjie
Last active August 29, 2015 13:56
Show Gist options
  • Save benjie/9233079 to your computer and use it in GitHub Desktop.
Save benjie/9233079 to your computer and use it in GitHub Desktop.
Mocha uncaughtException workaround

Workaround Mocha's Assertion Catching

(For Node.js only.)

To protect mocha tests (and before and after commands) from uncaught exceptions, in each test file:

{protect} = require './test_helper'
protect()

describe 'my thing', ->
  it 'does something', (done) ->
    ...

Frustratingly you have to call it in each test file as mocha effectively redefines it, before and after on every file it runs.

NOTE: This used to use domains, but it turns out Mocha just messes up the uncaughtException handler; so we get rid of Mocha's and use our own. Simples.

domain = require 'domain'
safe = (fn) ->
return fn if fn.isSafe
if fn.length > 0
originalFn = fn
worker = (args..., cb) ->
callback = (err, args...) ->
process.removeListener 'uncaughtException', callback
cb err, args...
process.removeAllListeners 'uncaughtException'
process.on 'uncaughtException', callback
ret = originalFn.apply this, [args..., callback]
return ret
fn =
switch originalFn.length
when 1 then (a) -> worker.apply this, arguments
when 2 then (a, b) -> worker.apply this, arguments
when 3 then (a, b, c) -> worker.apply this, arguments
when 4 then (a, b, c, d) -> worker.apply this, arguments
else
throw new Error("Cannot handle function of arity #{originalFn.length}")
fn.isSafe = true
return fn
makeSafe = (it) ->
return it if it.isSafe
originalIt = it
it = (args..., fn) ->
originalIt.apply this, [args..., safe fn]
it.isSafe = true
return it
protect = ->
global.it = makeSafe global.it
global.before = makeSafe global.before
global.after = makeSafe global.after
return global
module.exports = {protect}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment