Skip to content

Commit

Permalink
feat: Fail on launcher-, reporter-, or preprocessor-load errors.
Browse files Browse the repository at this point in the history
Fail out of karma if a launcher, reporter, or preprocessor fails to
load, after attempting to load each of them, and reporting errors for
each load error.

Closes karma-runner#855
  • Loading branch information
srawlins authored and budde377 committed Feb 23, 2016
1 parent d3bec1e commit 0a05504
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 37 deletions.
7 changes: 4 additions & 3 deletions lib/launcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,13 @@ var Launcher = function (emitter, injector) {
var browser = injector.createChild([locals], ['launcher:' + name]).get('launcher:' + name)
} catch (e) {
if (e.message.indexOf('No provider for "launcher:' + name + '"') !== -1) {
log.warn('Can not load "%s", it is not registered!\n ' +
'Perhaps you are missing some plugin?', name)
log.error('Cannot load browser "%s": it is not registered! ' +
'Perhaps you are missing some plugin?', name)
} else {
log.warn('Can not load "%s"!\n ' + e.stack, name)
log.error('Cannot load browser "%s"!\n ' + e.stack, name)
}

emitter.emit('load_error', 'launcher', name)
return
}

Expand Down
67 changes: 35 additions & 32 deletions lib/preprocessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ var createNextProcessor = function (preprocessors, file, done) {
}
}

var createPreprocessor = function (config, basePath, injector) {
var alreadyDisplayedWarnings = {}
var createPreprocessor = function (config, basePath, injector, emitter) {
var alreadyDisplayedErrors = {}
var instances = {}
var patterns = Object.keys(config)

var instantiatePreprocessor = function (name) {
if (alreadyDisplayedWarnings[name]) {
if (alreadyDisplayedErrors[name]) {
return
}

Expand All @@ -52,13 +52,13 @@ var createPreprocessor = function (config, basePath, injector) {
p = injector.get('preprocessor:' + name)
} catch (e) {
if (e.message.indexOf('No provider for "preprocessor:' + name + '"') !== -1) {
log.warn('Can not load "%s", it is not registered!\n ' +
'Perhaps you are missing some plugin?', name)
log.error('Can not load "%s", it is not registered!\n ' +
'Perhaps you are missing some plugin?', name)
} else {
log.warn('Can not load "%s"!\n ' + e.stack, name)
log.error('Can not load "%s"!\n ' + e.stack, name)
}

alreadyDisplayedWarnings[name] = true
alreadyDisplayedErrors[name] = true
emitter.emit('load_error', 'preprocessor', name)
}

return p
Expand All @@ -85,37 +85,40 @@ var createPreprocessor = function (config, basePath, injector) {
var nextPreprocessor = createNextProcessor(preprocessors, file, done)

for (var i = 0; i < patterns.length; i++) {
if (mm(file.originalPath, patterns[i], {dot: true})) {
if (thisFileIsBinary) {
log.warn('Ignoring preprocessing (%s) %s because it is a binary file.',
config[patterns[i]].join(', '), file.originalPath)
} else {
config[patterns[i]].forEach(function (name) {
var p = instances[name]
if (p == null) {
p = instantiatePreprocessor(name)
}

if (p == null) {
if (!alreadyDisplayedWarnings[name]) {
alreadyDisplayedWarnings[name] = true
log.warn('Failed to instantiate preprocessor %s', name)
}
return
}

instances[name] = p
preprocessors.push(p)
})
}
if (!mm(file.originalPath, patterns[i], {dot: true})) continue

if (thisFileIsBinary) {
log.warn('Ignoring preprocessing (%s) %s because it is a binary file.',
config[patterns[i]].join(', '), file.originalPath)
continue
}

config[patterns[i]].forEach(function (name) {
var p = instances[name]

if (p == null) {
p = instantiatePreprocessor(name)
}

if (p == null) {
if (!alreadyDisplayedErrors[name]) {
alreadyDisplayedErrors[name] = true
log.error('Failed to instantiate preprocessor %s', name)
emitter.emit('load_error', 'preprocessor', name)
}
return
}

instances[name] = p
preprocessors.push(p)
})
}

nextPreprocessor(null, thisFileIsBinary ? buffer : buffer.toString())
})
})
}
}
createPreprocessor.$inject = ['config.preprocessors', 'config.basePath', 'injector']
createPreprocessor.$inject = ['config.preprocessors', 'config.basePath', 'injector', 'emitter']

exports.createPreprocessor = createPreprocessor
5 changes: 3 additions & 2 deletions lib/reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,12 @@ var createReporters = function (names, config, emitter, injector) {
reporters.push(injector.createChild([locals], ['reporter:' + name]).get('reporter:' + name))
} catch (e) {
if (e.message.indexOf('No provider for "reporter:' + name + '"') !== -1) {
log.warn('Can not load "%s", it is not registered!\n ' +
log.error('Can not load reporter "%s", it is not registered!\n ' +
'Perhaps you are missing some plugin?', name)
} else {
log.warn('Can not load "%s"!\n ' + e.stack, name)
log.error('Can not load "%s"!\n ' + e.stack, name)
}
emitter.emit('load_error', 'reporter', name)
return
}
var color_name = name + '_color'
Expand Down
11 changes: 11 additions & 0 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ var Server = function (cliOptions, done) {

this.log = logger.create()

this.loadErrors = []

var config = cfg.parseConfig(cliOptions.configFile, cliOptions)

var modules = [{
Expand Down Expand Up @@ -135,6 +137,10 @@ Server.prototype._start = function (config, launcher, preprocess, fileList, webS

self._fileList = fileList

self.on('load_error', function (type, name) {
self.loadErrors.push([type, name])
})

config.frameworks.forEach(function (framework) {
self._injector.get('framework:' + framework)
})
Expand Down Expand Up @@ -175,6 +181,11 @@ Server.prototype._start = function (config, launcher, preprocess, fileList, webS
singleRunDoneBrowsers[browserLauncher.id] = false
})
}

if (self.loadErrors.length > 0) {
self.log.info('At least one plugin failed to load. Stopping Karma.')
process.kill(process.pid, 'SIGINT')
}
})
}

Expand Down

0 comments on commit 0a05504

Please sign in to comment.