Pipeline Error Handling

What is Pipeline Error Handling?

In case an error occurs during execution of a command/pipeline, the execution of the command and the according pipeline stops by default and an error message is sent back to the caller. You have different options to adjust this default behaviour and to handle such errors.

Stop (default)

If you would like to stop execuction of the command and/or the pipeline in case an error occurs, you need to set the action of the pipeline header onError to THROW.

In this case, the full stacktrace message about the error will be logged and after this, the execution of the command and/or the pipeline will stop.

In case the optional header/parameter onError is missing, THROW is used as the default behaviour.

Here is an example to set this header in a pipeline:

headers: onError: {"action": "THROW"} pipeline: - command.a: paramA: valueA - command.b: paramB: valueB

You can also use the short form like this:

headers: onError: "THROW" pipeline: - command.a: paramA: valueA - command.b: paramB: valueB

You can specify this also as parameter per command:

pipeline: - command.a: paramA: valueA onError: {"action": "THROW"} - command.b: paramB: valueB

Or in short:

Ignore

In order to ignore the error, you can set the action of the pipeline header onError to IGNORE.

In this case, a short message about the error will be logged and after this, the pipeline will go on with the next command. Here is an example to set this header globally for all commands in a pipeline:

You can also use the short form like this:

You can specify this also as parameter per command:

Or in short:

In case you specify onError as Pipeline header and as Command parameter, the parameter will have precedence.

Ignore + log

In order to ignore the error, but log the full stack trace with all detail information, you can set the action of the pipeline header onError to LOG.

In this case, the full stack trace message about the error will be logged and after this, the pipeline will go on with the next command.

Here is an example to set this header in a pipeline:

You can also use the short form like this:

You can specify this also as parameter per command:

Or in short:

In case you specify onError as Pipeline header and as Command parameter, the parameter will have precedence.

Rollback

This action is currently a preview and not activated in production versions.

If you would like to execute some rollback actions in case an error occured in a command, you need to set the action parameter of the pipeline header onError to ROLLBACK and additionally specify the parameter pipeline.

In this case, the full stack trace message about the error will be logged and after this, the given pipeline will be executed which contains the rollback logics.

Here is an example to set this header in a pipeline:

In case an error occurs, the persisted pipeline global/app/myapp/pipeline/rollback will be loaded from the property store and executed.

You can specify this also as parameter per command:

In case you specify onError as Pipeline header and as Command parameter, the parameter will have precedence.

There is no short form for this action.

Retry

It's also possible to retry a command after an error has been occurred, executing it. In this case, after the wait amount of seconds, the command will be re-executed the configured amount of times.

And finally, if the error still exists, a final action will be executed, defined by then.

Here is an example to set this header in a pipeline:

Or shorter:

You can specify this also as parameter per command:

Or shorter:

In case you specify onError as Pipeline header and as Command parameter, the parameter will have precedence.

In case an error happens in this example, the system will wait for 2 seconds and then will re-execute the same command. This will be repeated for 3 times. And if after 3 times the error still occurs, then the THROW action will be executed, which logs the error stack trace and then stops executing the command/pipeline. Instead of THROW you can also define any of the other actions mentioned before in short or long form including their parameters, except the RETRY action.

Parameters

The optional parameters of the RETRY action are:

  • wait: The time to wait in seconds before the next retry starts. Defaults to 3 seconds.

  • times: The number of retries before giving up and executing the then action. Defaults to 1.

  • then: The final action to do in case the error still occurs after the given amount of retries. Can be one of IGNORE, LOG, THROW or ROLLBACK. Defaults to THROW.

Finally

Sometimes it is necessary to do some tasks at the very end of a pipeline, even if an error has been occurred. For example to cleanup data. In such a case you can use the finally command: Every command which is defined after the finally command will be executed in any case at the very and of a pipeline.

There can be only one finally command per pipeline!

Here is an example:

Accessing the exception

In case an error (exception) happened in previous commands, this exception can be accessed inside the finally block using ${exception}, otherwise this implicit object is null.

Example:

In this example the finally parameter drop: true makes sure that the exception will be handled by the finally block and is not re-thrown to the client (it will be “dropped”). If not set or set to false, the exception can be handled in the finally block but will then be automatically re-thrown.

Using the if parameter on the mail.send command we check whether an exception happened: ${exception != null}. And if so, we will send an email containing the concrete exception message. This way you can define several commands and define whether they should handle the exception or not.

Also see: https://logabit.atlassian.net/wiki/spaces/PA/pages/2552856577/#exception

Catching exceptions

In some cases it is necessary to catch exceptions of certain types and handle them accordingly inside the pipeline.

This can be done using the except command.

Here is an example which catches all exceptions:

In case an exception happens, the pipeline execution flow will jump to the first except command after the command which caused the exception and then the body commands of this except command will be executed until the except.end command.

After an exception happened, you can access it using the implicit exception object. For more information about this object, see: https://logabit.atlassian.net/wiki/spaces/PA/pages/2552856577/#exception.

Catch exceptions of certain types

You can use the type parameter of the except command to define the names of one or more exceptions to be handled. For example:

In this case, only exceptions of type CommandException or HttpCommandException will be handled. All other exceptions will be re-thrown by the pipeline.

Since type is the default parameter of the except command, you can also use the “one-liner” format like this:

 

See the reference docs for the most common exception types:
https://logabit.atlassian.net/wiki/spaces/PA/pages/2552856577#exception.type

Drop or re-throw an exception

By default any exception handled by the except command will be dropped.

In case you would like to re-throw it, use the parameter drop and set it to false: