Skip to content

Commit

Permalink
fix: handle unexpected error when generating code coverage
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
devoto13 authored and Jonathan Ginsburg committed Feb 5, 2022
1 parent 44b31eb commit bca2c69
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 9 deletions.
23 changes: 14 additions & 9 deletions lib/reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,15 +290,20 @@ var CoverageReporter = function (rootConfig, helper, logger, emitter) {
}

this.onExit = async function (done) {
const results = await promiseComplete
if (results && results.exitCode === 1) {
done(results.exitCode)
return
}
if (typeof config._onExit === 'function') {
config._onExit(done)
} else {
done()
try {
const results = await promiseComplete
if (results && results.exitCode === 1) {
done(results.exitCode)
return
}
if (typeof config._onExit === 'function') {
config._onExit(done)
} else {
done()
}
} catch (e) {
log.error('Unexpected error while generating coverage report.\n', e)
done(1)
}
}
}
Expand Down
32 changes: 32 additions & 0 deletions test/reporter.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -584,5 +584,37 @@ describe('reporter', () => {
expect(log.warn).to.have.been.called
expect(done.calledOnce).to.be.true
})

it('should handle unexpected errors during the coverage generation', async () => {
const errorSpy = sinon.spy()
const doneSpy = sinon.spy()

const customLogger = {
create: () => {
return {
debug () {},
info () {},
warn () {},
error: errorSpy
}
}
}

const error = new Error('Directory creation failed!')

const customHelper = {
...mockHelper,
mkdirIfNotExists: async (_, done) => done(error)
}

reporter = new m.CoverageReporter(rootConfig, customHelper, customLogger)
reporter.onRunStart()
browsers.forEach(b => reporter.onBrowserStart(b))
reporter.onRunComplete(browsers)
await reporter.onExit(doneSpy)

expect(errorSpy).to.have.been.calledOnceWith('Unexpected error while generating coverage report.\n', error)
expect(doneSpy).to.have.been.calledOnceWith(1)
})
})
})

0 comments on commit bca2c69

Please sign in to comment.