diff --git a/example.js b/example.js
index c0827da..ea62dbf 100644
--- a/example.js
+++ b/example.js
@@ -19,7 +19,7 @@ const tasks = new Listr([
delay(2000)
.then(() => {
- observer.next(`bar`);
+ observer.next('bar');
return delay(2000);
})
.then(() => {
@@ -79,6 +79,6 @@ const tasks = new Listr([
renderer
});
-tasks.run().catch(err => {
- console.error(err.message);
+tasks.run().catch(error => {
+ console.error(error.message);
});
diff --git a/index.js b/index.js
index 5819627..3554e7c 100644
--- a/index.js
+++ b/index.js
@@ -32,7 +32,8 @@ class Listr {
showSubtasks: true,
concurrent: false,
renderer: 'default',
- nonTTYRenderer: 'verbose'
+ nonTTYRenderer: 'verbose',
+ failParentTaskOnErrors: true
}, opts);
this._tasks = [];
@@ -98,20 +99,20 @@ class Listr {
return tasks
.then(() => {
- if (errors.length > 0) {
- const err = new ListrError('Something went wrong');
- err.errors = errors;
- throw err;
+ if (this._options.failParentTaskOnErrors && errors.length > 0) {
+ const error = new ListrError('Something went wrong');
+ error.errors = errors;
+ throw error;
}
this._renderer.end();
return context;
})
- .catch(err => {
- err.context = context;
- this._renderer.end(err);
- throw err;
+ .catch(error => {
+ error.context = context;
+ this._renderer.end(error);
+ throw error;
});
}
}
diff --git a/lib/task.js b/lib/task.js
index 2315d54..9413e7e 100644
--- a/lib/task.js
+++ b/lib/task.js
@@ -171,29 +171,29 @@ class Task extends Subject {
this.state = state.COMPLETED;
}
})
- .catch(err => {
+ .catch(error => {
this.state = state.FAILED;
- if (err instanceof ListrError) {
- wrapper.report(err);
+ if (error instanceof ListrError) {
+ wrapper.report(error);
return;
}
if (!this.hasSubtasks()) {
// Do not show the message if we have subtasks as the error is already shown in the subtask
- this.output = err.message;
+ this.output = error.message;
}
this.next({
type: 'DATA',
- data: err.message
+ data: error.message
});
- wrapper.report(err);
+ wrapper.report(error);
if (this._listr.exitOnError !== false) {
// Do not exit when explicitely set to `false`
- throw err;
+ throw error;
}
})
.then(() => {
diff --git a/readme.md b/readme.md
index a2ea329..dcb99dc 100644
--- a/readme.md
+++ b/readme.md
@@ -406,6 +406,14 @@ Default: `true`
Set to `false` if you don't want to stop the execution of other tasks when one or more tasks fail.
+##### failParentTaskOnErrors
+
+Type: `boolean`
+Default: `true`
+
+Set to `false` if you don't want show failed state in parent task when a sub tasks fails.
+
+
##### renderer
Type: `string` `object`
diff --git a/test/exit-on-error.js b/test/exit-on-error.js
index e9bfcf6..4c34d0a 100644
--- a/test/exit-on-error.js
+++ b/test/exit-on-error.js
@@ -30,8 +30,8 @@ test('exit on error', async t => {
try {
await list.run();
- } catch (err) {
- t.is(err.message, 'Something went wrong');
+ } catch (error) {
+ t.is(error.message, 'Something went wrong');
}
});
@@ -54,9 +54,9 @@ test('set `exitOnError` to false', async t => {
try {
await list.run();
- } catch (err) {
- t.is(err.message, 'Something went wrong');
- t.is(err.errors.length, 1);
+ } catch (error) {
+ t.is(error.message, 'Something went wrong');
+ t.is(error.errors.length, 1);
}
});
@@ -110,10 +110,10 @@ test('set `exitOnError` to false in nested list', async t => {
try {
await list.run();
- } catch (err) {
- t.is(err.message, 'Something went wrong');
- t.is(err.errors.length, 1);
- t.is(err.errors[0].message, 'Unicorn failed');
+ } catch (error) {
+ t.is(error.message, 'Something went wrong');
+ t.is(error.errors.length, 1);
+ t.is(error.errors[0].message, 'Unicorn failed');
}
});
@@ -167,14 +167,67 @@ test('set `exitOnError` to false in root', async t => {
try {
await list.run();
- } catch (err) {
- t.is(err.name, 'ListrError');
- t.is(err.errors.length, 2);
- t.is(err.errors[0].message, 'Foo failed');
- t.is(err.errors[1].message, 'Unicorn failed');
+ } catch (error) {
+ t.is(error.name, 'ListrError');
+ t.is(error.errors.length, 2);
+ t.is(error.errors[0].message, 'Foo failed');
+ t.is(error.errors[1].message, 'Unicorn failed');
}
});
+test('set `exitOnError` to false in root, set `failParentTaskOnErrors` to false in child task and do not raise ListError', async t => {
+ t.plan(13);
+
+ const list = new Listr([
+ {
+ title: 'foo',
+ task: () => Promise.reject(new Error('Foo failed'))
+ },
+ {
+ title: 'bar',
+ task: () => {
+ return new Listr([
+ {
+ title: 'unicorn',
+ task: () => Promise.reject(new Error('Unicorn failed'))
+ },
+ {
+ title: 'rainbow',
+ task: () => Promise.resolve()
+ }
+ ], {
+ failParentTaskOnErrors: false
+ });
+ }
+ },
+ {
+ title: 'baz',
+ task: () => Promise.resolve()
+ }
+ ], {
+ exitOnError: false,
+ renderer: SimpleRenderer
+ });
+
+ testOutput(t, [
+ 'foo [started]',
+ 'foo [failed]',
+ '> Foo failed',
+ 'bar [started]',
+ 'unicorn [started]',
+ 'unicorn [failed]',
+ '> Unicorn failed',
+ 'rainbow [started]',
+ 'rainbow [completed]',
+ 'bar [completed]',
+ 'baz [started]',
+ 'baz [completed]',
+ 'done'
+ ]);
+
+ await list.run();
+});
+
test('set `exitOnError` to false in root and true in child', async t => {
t.plan(16);
@@ -226,11 +279,11 @@ test('set `exitOnError` to false in root and true in child', async t => {
try {
await list.run();
- } catch (err) {
- t.is(err.name, 'ListrError');
- t.is(err.errors.length, 2);
- t.is(err.errors[0].message, 'Foo failed');
- t.is(err.errors[1].message, 'Unicorn failed');
+ } catch (error) {
+ t.is(error.name, 'ListrError');
+ t.is(error.errors.length, 2);
+ t.is(error.errors[0].message, 'Foo failed');
+ t.is(error.errors[1].message, 'Unicorn failed');
}
});
@@ -264,10 +317,10 @@ test('exit on error throws error object with context', async t => {
try {
await list.run();
- } catch (err) {
- t.is(err.name, 'ListrError');
- t.is(err.errors.length, 1);
- t.is(err.errors[0].message, 'Foo failed');
- t.deepEqual(err.context, {foo: 'bar'});
+ } catch (error) {
+ t.is(error.name, 'ListrError');
+ t.is(error.errors.length, 1);
+ t.is(error.errors[0].message, 'Foo failed');
+ t.deepEqual(error.context, {foo: 'bar'});
}
});
diff --git a/test/test.js b/test/test.js
index b1d4d1d..be1306e 100644
--- a/test/test.js
+++ b/test/test.js
@@ -192,9 +192,9 @@ test('context is attached to error object', async t => {
try {
await list.run();
t.fail('Should throw error');
- } catch (err) {
- t.is(err.message, 'foo bar');
- t.deepEqual(err.context, {
+ } catch (error) {
+ t.is(error.message, 'foo bar');
+ t.deepEqual(error.context, {
foo: 'bar'
});
}