Skip to content

FAIL

Stops the rule with a message you write. Nothing after it in the rule runs. In a rule that fires from the interface, such as a form check or a status change, the message comes back to the person who pressed the button and the action is refused. In a job, the step ends and the job goes to ERROR.

Reach for it once a check has already decided the run should not continue. To record something and carry on, use LOG message instead. FAIL raises an ordinary error, so every error handler in the rule tree above it gets a chance to intercept it.

FAIL is anything above handling errors? CATCH runs, the rule carries on job waits for an operator job ends in ERROR and the rollback pass may start

Fields

Error Message

Free text over as many lines as you need. The box arrives pre-filled with abort here, and that is also what you get back if you clear it: an empty box falls back to abort here in the reader's language. Leading and trailing whitespace is trimmed.

${var} placeholders expand against the stash at the moment the op runs, so ${jobname} and ${topic.title} both work. A placeholder that resolves to nothing is left in the message exactly as you typed it, which is how you spot a misspelt variable name. Write $${var} to print a literal ${var}. Full syntax is in Variable Parsing.

Nothing in the message is treated as code. Quotes and backslashes reach the reader as you typed them, and a percent sign is never read as a placeholder.

Allow HTML? (make sure no user data present)

Off by default, and with it off the angle brackets in your message are escaped, so <b>bar</b> arrives with the tags showing rather than a word in bold. Turn it on and the message is rendered as markup in the error dialog, which is how messages with coloured text and horizontal rules get their formatting.

The parenthetical in the label is the real constraint. The message becomes part of the page. If any piece of it arrives through a stash variable that a user can type into, leave this off.

Remove Message Headers?

Off by default. A failure is normally shown wrapped in the context that produced it, so a FAIL raised while a comment is being added reads Error adding Comment: your text, and a FAIL inside a job step is logged as Job failure: your text. Turn this on and the wrapper is dropped, leaving only your message.

Both checkboxes are independent and can be on together. That combination is the usual one for a hand-formatted validation message.

Where the message ends up

In a rule triggered from the interface, the message is what the user sees in the error dialog. That is the main use of this op: refuse the action and explain why it was refused.

In a job, the failure produces one entry in the job log. Only the text up to the first blank line reaches that entry, so a long message with paragraph breaks looks truncated. Keep the sentence that matters on the first line. The job also records the failure text on the job itself, capped at the first 1024 characters.

The op's own trace of the message is written at debug level, so unless the job runs with extra debug turned on, that single log entry is all you get. Wrapped in a TRY statement with no CATCH, you get nothing at all.

What the failure does

FAIL is an error like any other, and it is intercepted in the same places:

  • A CATCH statement attached to an enclosing TRY handles it and the rule continues from after the CATCH.
  • An enclosing op with Error Handling set to Trap Errors puts the job in TRAPPED and waits for someone to answer Retry, Skip, Abort or Pause. Set to Ignore Errors, the failure disappears and the rule continues. Those settings live on the enclosing op's Options tab, described in Rule Palette.
  • Unhandled in a job, the step ends. If any op up to that point recorded a rollback need, the rollback pass starts. If none did, the job stops at ERROR with no second pass.
  • FAIL during the rollback pass aborts the rollback and leaves it half done. Guard it with IF ROLLBACK when that is not what you want.

FAIL holds no nested ops. It is always a leaf.

Combining with other ops

Put it under IF var condition THEN to turn a stash check into a hard stop. That pair covers most form validation: test the value, fail with an explanation.

Wrap a block in TRY statement plus CATCH statement and put a FAIL inside the CATCH when you want readable wording instead of whatever the failing op threw. The original text is waiting in _last_error, so ${_last_error} can be pasted into your own sentence.

RETRY statement around a flaky block turns a FAIL inside it into another attempt rather than a stop, which is rarely what you want. Keep FAIL outside the retried block.

Examples

Refuse a topic that has no application selected on its parent. No markup, no wrapper text.

Error Message              Pick an application on the parent topic first.
Allow HTML?                off
Remove Message Headers?    on

A formatted warning that names the offending category, the shape most validation messages take.

Error Message              <hr><span style="color:red;">No more topics allowed
                           in category ${category_name}.</span>
Allow HTML?                on
Remove Message Headers?    on

Stop a job step and carry the count into the log entry. The first line is the one the job log keeps.

Error Message              Build rejected: ${build_errors} error(s) on ${myapp_host}.
Allow HTML?                off
Remove Message Headers?    off