Handling Errors

Introduction

You can throw errors out of the tasks to show they are unsuccessful. While this gives a visual output on the terminal, it also handles how to handle tasks that are failed. The default behavior is any of the tasks have failed, it will deem itself as unsuccessful and exit. This behavior can be changed with exitOnError option. If the exitOnError is true, the first error encountered will be thrown out again.

If you want to quit the application pre-maturely and fail a specific task just throw out an Error.

An Error should be always a real Error type extended from the JavaScript/Typescript Error class.

Throwing Out an Error

Throwing an error will stop any further action whether it is in running with concurrent flag or not.

You don't have to catch errors explicitly since they will always be collected by Listr.

Be aware that the execution will only stop after the error is thrown out. This can kill any asynchronous action pre-maturely.

new Listr<Ctx>(
  [
    {
      title: 'This task will fail.',
      task: async (): Promise<void> => {
        await delay(2000)
        throw new Error('This task failed after 2 seconds.')
      }
    },
    {
      title: 'This task will never execute.',
      task: (ctx, task): void => {
        task.title = 'I will change my title if this executes.'
      }
    }
  ],
  { concurrent: false }
)

Changing the Behavior

Per Listr

new Listr<Ctx>(
  [
    {
      title: 'This task will fail.',
      task: async (): Promise<void> => {
        await delay(2000)
        throw new Error('This task failed after 2 seconds.')
      }
    },
    {
      title: 'This task will execute.',
      task: (ctx, task): void => {
        task.title = 'I will change my title if this executes.'
      }
    }
  ],
  { concurrent: false, exitOnError: false }
)

Per Subtask

new Listr<Ctx>(
  [
    {
      title: 'This task will execute and not quit on errors.',
      task: (ctx, task): Listr =>
        task.newListr(
          [
            {
              title: 'This is a subtask.',
              task: async (): Promise<void> => {
                throw new Error('I have failed [0]')
              }
            },
            {
              title: 'This is yet an another subtask and it will run.',
              task: async (ctx, task): Promise<void> => {
                task.title = 'I have succeeded.'
              }
            }
          ],
          { exitOnError: false }
        )
    },
    {
      title: 'This task will execute.',
      task: (): void => {
        throw new Error('I will exit on error since I am a direct child of parent task.')
      }
    }
  ],
  { concurrent: false, exitOnError: true }
)

Per Task

task = new Listr<Ctx>(
  [
    {
      title: 'This task will fail.',
      task: async (): Promise<void> => {
        await delay(2000)
        throw new Error('This task failed after 2 seconds.')
      },
      exitOnError: false
    },
    {
      title: 'This task will execute.',
      task: (_, task): void => {
        task.title = 'I will change my title if this executes.'
      }
    }
  ],
  {
    concurrent: false,
    exitOnError: true
  }
)

Renderer

Default Renderer

/**
 * shows the thrown error message or show the original title of the task, this will also disable collapseErrors mode
 * You can disable showing the error messages, even though you passed in a message by settings this option,
 * if you want to keep the original task title intact.
 *
 * @default true
 */
showErrorMessage?: boolean
/**
 * collapse error messages into a single message and overwrite the task title
 *
 * @default true
 */
collapseErrors?: boolean
Edit this page on GitHub Updated at Tue, Feb 1, 2022