Concepts / Error Handling Strategies

Error Handling Strategies

The Guardian Pattern strategically places a guard condition before a risky operation in an 'and' expression to prevent runtime errors.

  • Programming

Preventing the Failure

A runtime error can occur when a program performs an operation before confirming that the operation is safe. The Guardian Pattern addresses this by placing a guard condition before the risky operation in an and expression. If the guard is false, short-circuit evaluation stops the expression, so the later operation is not run.

Following the Short-Circuit Path

check firstfalsetrueand expressionevaluation beginsguard conditionexpression stopsguard is falserisky operationevaluated only when reached
How does the guard condition determine whether the risky operation is evaluated?

The Guardian Pattern depends on short-circuit evaluation. The expression checks the guard first. When that condition is false, evaluation stops immediately. Because evaluation stops, the subsequent risky operation is prevented from running. When the guard is true, evaluation can continue to the operation that follows it.

What do you think happens?

Suppose an and expression checks whether a denominator is non-zero before using that denominator in a calculation. What should happen when the denominator is zero?

  • The guard becomes false and the later operation is skipped.
  • The later operation always runs before the guard.
  • The guard changes the denominator to a different value.
Reveal answer

Answer: The guard becomes false and the later operation is skipped.

Short-circuit evaluation stops the expression as soon as a condition is false, so the later operation is not run.

A Guarded Calculation

Checking a Denominator Before Use

Construct an and expression that uses a denominator only after checking that it is non-zero.

Name the risk: The risky part is the calculation that uses the denominator.

Create the guard: Use a condition that checks whether the denominator is non-zero.

Place the guard first: Put the non-zero check before the calculation in the and expression.

Follow the false path: If the denominator is zero, the guard is false, short-circuit evaluation stops, and the calculation is not evaluated.

Follow the true path: If the denominator is non-zero, the guard is true, so evaluation may continue to the calculation.

The guarded expression protects the calculation because the condition that establishes safety appears before the operation that depends on it.

The important feature of this example is not the particular calculation. It is the dependency order: first establish that the denominator is safe, then allow the calculation that uses it to be considered. The guard is useful because it controls whether the risky operation is reached.

inspectunsafesafecandidate valuesafety guardoperation skippedguard is falserisky operationguard is true
How does a guard prevent execution from reaching an operation that could cause a runtime error?

Ordering the Conditions

In a guarded logical expression, the conditions are not interchangeable. The guard must appear before the operation it protects. This ordering allows a false guard to stop evaluation before the risky operation is reached. If the risky operation appears first, it may be evaluated before the program checks the condition intended to protect it.

safe orderunsafe orderguard conditionchecked firstrisky operationchecked firstrisky operationchecked secondguard conditionchecked second
What changes when the safe guard is placed before versus after the risky operation?
Condition orderWhat happens when the guard is falseProtection
Guard, then risky operationShort-circuit evaluation can stop before the risky operationThe intended Guardian Pattern
Risky operation, then guardThe risky operation may already have been evaluatedThe guard may fail to protect the operation

When Protection Fails

incorrect orderprotective orderrisky operationfirstguard conditionfirstguard conditionsecondrisky operationsecond
Why does the expression still produce a runtime error when the risky operation is evaluated before the guard?
  • Putting the guard after the risky operation

    Short-circuit evaluation can stop only at the point where a false condition is encountered. A later guard cannot undo an operation that has already been evaluated.

    Fix: Move the guard before the risky operation.

  • Treating condition order as unimportant

    The Guardian Pattern relies on the guard being evaluated first.

    Fix: Identify the operation that could cause a runtime error, then place its safety check before it.

  • Using a guard that does not establish the needed safety

    A condition protects an operation only when it checks the relevant safety requirement.

    Fix: Match the guard to the risk: check for a non-zero denominator before using it, a valid array index before accessing an array position, or valid data before using that data in a calculation.

Building the Expression

  1. Identify the operation that could produce a runtime error.
  2. Determine the condition that would make that operation safe.
  3. Place the safety condition first in the and expression.
  4. Place the risky operation after the guard.
  5. Trace the false-guard path and confirm that short-circuit evaluation stops before the risky operation.
  6. Trace the true-guard path and confirm that evaluation can continue to the operation.
firstthenguard conditionestablishes safetyandshort-circuit linkrisky operationdepends on the guard
How should the conditions be arranged so that the guard is checked before accessing or performing the risky operation?

The reusable structure is: relevant safety check, then and, then dependent operation. The safety check comes first because a false result must be able to stop evaluation before the dependent operation runs.

Practice the Guard

MEDIUM

For each situation, identify the guard and the risky operation, then describe their correct order in an and expression: a calculation involving a denominator, an access using an array index, and a calculation using data whose validity has not yet been confirmed.

Hints
  • The guard should state the safety condition relevant to the risk.
  • Place the guard before the operation it protects.
  • Ask what must be true before the operation can safely be considered.

A strong answer should name both parts of each pair. For the denominator case, the guard checks for a non-zero denominator. For the array case, the guard checks for a valid index. For the data case, the guard checks that the data is valid. In every case, the guard comes before the operation that uses the value.

Key Takeaways

  1. The Guardian Pattern places a guard condition before a risky operation in an and expression.
  2. Short-circuit evaluation stops the expression when a condition is false.
  3. A guard can prevent a later operation from running and thereby prevent a runtime error.
  4. Condition order is essential: the guard must come before the operation it protects.
  5. Useful guards check non-zero denominators, valid array indices, and valid data values.

Key Takeaways

  • The Guardian Pattern uses a safety condition before a risky operation.
  • Short-circuit evaluation prevents later operations from running when an earlier condition is false.
  • A guard fails to protect code when the risky operation is placed before the guard.
  • To construct a guarded expression, identify the risk, write its relevant safety check, and place that check first.