Bug Description
In packages/core/lib/phases.ts, the async.series completion callback swallows errors silently. When a phase fails (e.g., because of an unknown mode value), the error is only debug()-logged — invisible unless DEBUG=phases is set — and then 'done' is unconditionally emitted regardless. The runner then aggregates stats normally and reports clean completion with exit code 0, giving no indication that anything went wrong.
Affected code (packages/core/lib/phases.ts, around line 95)
ee.run = () => {
async.series(tasks, (err) => {
if (err) {
debug(err);
}
ee.emit('done'); // always fires, even on error
});
};
Steps to Reproduce
- Create a script with an invalid phase mode:
config:
target: "http://localhost:3000"
phases:
- duration: 10
arrivalRate: 5
mode: foobar # invalid mode
scenarios:
- flow:
- get:
url: "/"
- Run it:
- Observed: exits 0, no error output (unless
DEBUG=phases is set)
- Expected: exits non-zero with a visible error message about the unknown phase mode
Root Cause
createPhases iterates over the phase specs and pushes tasks into an array. For an unrecognised mode, it logs to console.log ("Unknown phase spec") but still returns undefined, contributing a no-op task. The async.series callback receives err only when a task itself calls back with an error — but even if it did, the current callback ignores that error path and always emits 'done'.
Suggested Fix
ee.run = () => {
async.series(tasks, (err) => {
if (err) {
debug(err);
ee.emit('error', err);
return;
}
ee.emit('done');
});
};
This ensures that any phase-level error surfaces through the event emitter so callers can handle it, log it visibly, and propagate a non-zero exit code.
Bug Description
In
packages/core/lib/phases.ts, theasync.seriescompletion callback swallows errors silently. When a phase fails (e.g., because of an unknownmodevalue), the error is onlydebug()-logged — invisible unlessDEBUG=phasesis set — and then'done'is unconditionally emitted regardless. The runner then aggregates stats normally and reports clean completion with exit code 0, giving no indication that anything went wrong.Affected code (
packages/core/lib/phases.ts, around line 95)Steps to Reproduce
DEBUG=phasesis set)Root Cause
createPhasesiterates over the phase specs and pushes tasks into an array. For an unrecognisedmode, it logs toconsole.log("Unknown phase spec") but still returnsundefined, contributing a no-op task. Theasync.seriescallback receiveserronly when a task itself calls back with an error — but even if it did, the current callback ignores that error path and always emits'done'.Suggested Fix
This ensures that any phase-level error surfaces through the event emitter so callers can handle it, log it visibly, and propagate a non-zero exit code.