Skip to content

Commit bca2c69

Browse files
devoto13Jonathan Ginsburg
authored andcommitted
fix: handle unexpected error when generating code coverage
The issue surfaced itself after d970028. The EEXIST error from concurrent attempts to create the same directory were previously silently swallowed, but started to show up once the call was properly synchronized. The EEXIST will now result in `promiseComplete` being rejected and reported as `unhandledRejection` because it is awaited in the `onExit` callback. The unhandled rejection is then picked up by `karma` [here](https://github.com/karma-runner/karma/blob/c985155a4eac95c525e1217e98d4013ac5f53305/lib/server.js#L395) triggering [the close logic](https://github.com/karma-runner/karma/blob/c985155a4eac95c525e1217e98d4013ac5f53305/lib/server.js#L392) which (among other things) will trigger `onExit` callback causing an infinite loop. The local fix is to handle the rejected promise directly and report failure to karma by passing a non-zero exit code.
1 parent 44b31eb commit bca2c69

File tree

2 files changed

+46
-9
lines changed

2 files changed

+46
-9
lines changed

lib/reporter.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -290,15 +290,20 @@ var CoverageReporter = function (rootConfig, helper, logger, emitter) {
290290
}
291291

292292
this.onExit = async function (done) {
293-
const results = await promiseComplete
294-
if (results && results.exitCode === 1) {
295-
done(results.exitCode)
296-
return
297-
}
298-
if (typeof config._onExit === 'function') {
299-
config._onExit(done)
300-
} else {
301-
done()
293+
try {
294+
const results = await promiseComplete
295+
if (results && results.exitCode === 1) {
296+
done(results.exitCode)
297+
return
298+
}
299+
if (typeof config._onExit === 'function') {
300+
config._onExit(done)
301+
} else {
302+
done()
303+
}
304+
} catch (e) {
305+
log.error('Unexpected error while generating coverage report.\n', e)
306+
done(1)
302307
}
303308
}
304309
}

test/reporter.spec.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,5 +584,37 @@ describe('reporter', () => {
584584
expect(log.warn).to.have.been.called
585585
expect(done.calledOnce).to.be.true
586586
})
587+
588+
it('should handle unexpected errors during the coverage generation', async () => {
589+
const errorSpy = sinon.spy()
590+
const doneSpy = sinon.spy()
591+
592+
const customLogger = {
593+
create: () => {
594+
return {
595+
debug () {},
596+
info () {},
597+
warn () {},
598+
error: errorSpy
599+
}
600+
}
601+
}
602+
603+
const error = new Error('Directory creation failed!')
604+
605+
const customHelper = {
606+
...mockHelper,
607+
mkdirIfNotExists: async (_, done) => done(error)
608+
}
609+
610+
reporter = new m.CoverageReporter(rootConfig, customHelper, customLogger)
611+
reporter.onRunStart()
612+
browsers.forEach(b => reporter.onBrowserStart(b))
613+
reporter.onRunComplete(browsers)
614+
await reporter.onExit(doneSpy)
615+
616+
expect(errorSpy).to.have.been.calledOnceWith('Unexpected error while generating coverage report.\n', error)
617+
expect(doneSpy).to.have.been.calledOnceWith(1)
618+
})
587619
})
588620
})

0 commit comments

Comments
 (0)