Skip to content

TRY statement

Runs the ops nested underneath it and absorbs any error they raise, so a failure inside the block does not end the rule. The palette offers two of them, TRY statement (without catch) and TRY statement (needs a catch). They behave identically up to the point of failure and differ only in what happens next.

Neither variant has any configuration. The Config tab holds the op's Name and an empty data editor, and nothing else. Everything on this page is fixed behaviour.

TRY statement (without catch) nested ops run until one fails error absorbed, the rest of the block is dropped silently the rule carries on TRY statement (needs a catch) nested ops run until one fails CATCH runs its nested ops, with _last_error the rule carries on

Which variant to pick

TRY statement (needs a catch) is the one to reach for. It has to be followed immediately by a CATCH statement, and the CATCH is where you log the problem, record a flag, or turn it into clearer wording with FAIL.

TRY statement (without catch) discards the error and writes nothing of its own: no job log entry, no job status change, no stash variable. Whatever the failing op logged on its way down is still there, so a failed remote script leaves its error line behind, but nothing records that the rest of the block was dropped. Someone reading the job afterwards sees a step that ended without complaint and half its work missing. Use it only where the work is genuinely optional, such as a best effort cleanup, and give the op a name that says so.

What the block does on failure

Ops inside run in order until one of them raises an error. That op stops where it is and the rest of the block is skipped. The block is not re-entered; there is no retry here. For that, use RETRY.

The error can come from anywhere inside, at any depth, including a rule pulled in by CALL rule, a failing remote script, or an explicit FAIL.

A rollback mark set by an op inside the block stays set. Absorbing the error does not clear it, so a later failure elsewhere in the job still rolls that op back. See rollback.

A cancel request raised against a running job reaches the rule as an error like any other, and the cancel is consumed once. A TRY around the op that receives it absorbs the cancellation and the job keeps going. Keep TRY blocks short for that reason alone.

Placement rules

These are strict, and getting them wrong produces a failure when the rule runs rather than a warning in the designer.

TRY statement (needs a catch) must be followed by a CATCH as the very next op at the same level in the tree. Anything in between, or no CATCH at all, and the rule stops with a complaint about an unexpected argument the first time it is executed.

TRY statement (without catch) must not be followed by a CATCH. A CATCH with no matching TRY in front of it stops the rule with a complaint about a useless bare catch.

Options tab

On TRY statement (without catch) every option behaves normally.

On TRY statement (needs a catch), leave the Options tab alone apart from Enabled. The Name field on the Config tab and the Note tab are safe too. Run Forward, Run Rollback, Needs Rollback?, Error Handling, Parallel Mode, Semaphore Key, Sub Name, Stage Name and a Debug Mode of Op Trace + Stash Dump each wrap extra work around the op, which pushes the CATCH out of reach and breaks the pair. Put those settings on the ops inside the block instead. The full list of options is described in Rule Palette.

The TRY op itself shows up in the job log as a step under its name, and ${var} placeholders in the name expand. The CATCH does not appear as a step of its own.

Combining with other ops

CATCH statement is the other half of the pair and reads the error text out of _last_error.

Error Handling set to Ignore Errors on a single op does what TRY statement (without catch) does for a whole block, and it writes a line into the job log saying the error was ignored. Prefer it when only one op is at risk.

Error Handling set to Trap Errors stops the job and asks a person what to do, instead of deciding for them. After that answer, IF last trap action THEN lets the rule branch on what they picked.

RETRY repeats a block a fixed number of times before giving up. A TRY placed inside the retried block hides the failure and defeats the retry, so put the TRY outside.

Examples

Best effort cleanup at the end of a step. The block is allowed to fail and the job does not care.

TRY statement (without catch)     named "remove scratch dir (optional)"
  Delete Local Directory          /tmp/foo_build

Catch a failing deployment, record it in the stash and let a later branch decide.

TRY statement (needs a catch)
  Run a remote script             deploy script on myapp
CATCH statement
  SET VAR                         deploy_failed = 1
  LOG message                     Deploy failed: ${_last_error}

Turn an obscure failure into wording the requester can act on.

TRY statement (needs a catch)
  Web Request                     POST to the bar service
CATCH statement
  FAIL                            The bar service refused the release: ${_last_error}