try

Catch pipeline errors

try

Normally when an action errors the pipeline execution is stopped immediately and a protocol specific error response is sent to the client. The try action can be used to convert the errors to ignore results.

Syntax

try <action>;
try <action> { }

Example

try backend "STORE_ACCOUNTING";
try backend {
  name "SQL_BACKEND";
  query "FIND_USER";
}

When combined with the first action, the try action can be used to fallback to a secondary action when the primary action fails:

first {
  try backend "PRIMARY_AUTH";
  try backend "SECONDARY_AUTH";
  error "All authentication backends failed";
}

Long form syntax

The try action also supports a long form syntax which includes a catch block which can be used for custom error handling

try [pipeline directive] {
    # actions
} catch {
    # Execute this pipeline if an error occurs in the main pipeline
}

When an error occurs in the main try pipeline, the actions in the catch block are executed. If no error occurs, the catch block is skipped. On error the result of the try action is the result of the last action in the catch block.

NOTE: If the try-block contains multiple actions, the execution is immediately moved to the catch-block upon the first error encountered. Actions after the error in the try-block are not executed.

try {
    backend "PRIMARY_AUTH"; # This action errors ❌
    backend "SECONDARY_AUTH"; # This action is not executed! 🚨
} catch {
    reject "operation failed";
}

Generally it is recommended to keep only one action in the try-block to avoid confusion.

Error Information

When an error is caught, the error message is made available in the aaa.caught_error variable. This variable contains only the most recent error message.

try {
    backend "FIND_USER";
} catch {
    reject "operation failed: %{aaa.caught_error}";
}
Error History

The aaa.caught_errors variable provides access to all caught errors as a collection. Unlike aaa.caught_error, which only contains the most recent error, aaa.caught_errors accumulates all errors caught during the request processing. This is useful when multiple try actions are used and you need to track all errors that occurred.

try backend "PRIMARY_AUTH";
try backend "SECONDARY_AUTH";

# Check if any errors occurred
if any {
  aaa.caught_errors != none
} then {
    debug "Errors occurred: %{aaa.caught_errors}";
}

# Get the count of caught errors
if all {
  aaa.caught_errors|count == 2
} then {
    debug "Both backends failed";
}
Clearing Errors

Both aaa.caught_error and aaa.caught_errors can be cleared manually using the modify action:

modify {
    aaa.caught_error = none;
    aaa.caught_errors = none;
}

Pipeline Directive

You may optionally specify a pipeline directive for the try block to control how non-error results are handled. If no pipeline directive is specified, the default while directive is used. See the documentation for pipeline directives

try first {
    pap;
    chap;
} catch {
    # Error handling...
}