CATCH statement
Runs the ops nested underneath it when the block above it failed, and does nothing when that block
succeeded. It is the second half of a pair: it only works directly after a
TRY statement (needs a catch), described in TRY statement. The palette
lists it as CATCH statement (needs a try_with_catch).
The op has no configuration of its own. Its Config tab holds the op's Name and an empty data
editor. What you get instead is the failure text, handed to you in the stash under _last_error.
What you get in the stash¶
Before the nested ops run, the failure text is written into the stash as
_last_error. Read it anywhere a stash variable is accepted, as ${_last_error} in a message
field or as the bare name _last_error in a condition row.
The text is whatever the failing op threw. For a FAIL it is the message you
wrote, after variable expansion. When the failure came from a job op rather than a control
statement, that message is wrapped before it reaches you: the text starts with Error running task,
then the failing op's name between asterisks, then a colon, then the original wording. Errors raised
by Clarive itself also end in a newline. Both are reasons to match _last_error with LIKE in
IF var condition THEN rather than comparing it for equality.
_last_error is never cleared. It stays in the stash for the rest of the job and carries into the
following job steps, so a test that reads it much later can be looking at an error from an earlier
step. Read it inside the CATCH block, copy what you need into a variable of your own, or remove it
with DELETE hashkey once you are done with it.
What the block does and does not do¶
CATCH does not re-raise. Once it finishes, the rule carries on with the next op after it, the job status is unaffected, and the job does not switch to its rollback pass on account of that failure. To end the run anyway, put a FAIL inside the CATCH.
An error raised inside the CATCH block is not caught by the same TRY. It escapes to whatever handling surrounds the pair, or ends the rule.
The CATCH op does not show up as a step of its own in the job log. The ops nested inside it do, so give those clear names. It is not a cancellation checkpoint either.
A rollback mark set by an op inside the failed TRY block stays set. Handling the error here does not clear it, so a later failure elsewhere in the job still rolls that op back. See rollback.
Placement rules¶
The CATCH must be the very next op after a TRY statement (needs a catch), at the same level in the
tree. Nothing may sit between them.
A CATCH that follows a TRY statement (without catch), or that sits on its own, stops the rule at
run time with a complaint about a useless bare catch. The designer does not warn you when you save.
One TRY takes exactly one CATCH. Drop a second CATCH after the first and the first one still runs to completion; the rule then dies on the second with the same useless-bare-catch complaint, leaving you with a half-handled error and a failed rule.
Clearing Enabled on the TRY removes the whole TRY block from the rule, nested ops included, and
leaves the CATCH with nothing in front of it. Disable the pair together or leave both alone.
Leave the Options tab at its defaults apart from Enabled. The Name field on the Config tab and
the Note tab are safe too. Error Handling, Parallel Mode, Run Forward, Run Rollback,
Needs Rollback?, Semaphore Key, Sub Name, Stage Name, a Timeout above zero and a
Debug Mode of Op Trace + Stash Dump each wrap extra work around the op, which pushes the CATCH
out of reach of the TRY. Put those settings on the ops nested inside instead. The options themselves
are covered in Rule Palette.
Combining with other ops¶
LOG Message inside the CATCH is the minimum worth doing. Without it, the only trace of the failure is whatever the failing op logged on its way out.
SET VAR inside the CATCH records that something went wrong, so a later IF var condition THEN can change what the rest of the rule does.
FAIL inside the CATCH replaces a machine-generated error with wording the person reading the job can act on.
Examples¶
Record the failure and keep going, so the rest of the step still runs.
TRY statement (needs a catch)
Run a remote script build script on myapp
CATCH statement
LOG Message Build step failed: ${_last_error}
SET VAR build_failed = 1
Branch on the kind of failure, using a pattern match against the captured text.
TRY statement (needs a catch)
Web Request GET the bar service status
CATCH statement
IF var condition THEN
When: Any
_last_error LIKE timed out (Ignore case)
LOG Message Bar service is slow, carrying on without it
ELSE
FAIL Bar service call failed: ${_last_error}