ApexSensei

Drills Classes & objects

finally and several catch blocks

Classes & objects · Intermediate · 14 min · Runs in your Salesforce Developer org · Free

Write `divide(Integer a, Integer b)` that catches two different exceptions with their own `catch` blocks and always appends ` (done)` from a `finally` block. Division by zero returns `error:zero`, a null input returns `error:null`, and a clean division returns `result:<value>`.

Lesson

Why this matters

Real code fails in different ways: a division by zero, a null input, a bad conversion. If one giant catch (Exception e) grabs them all, you lose the chance to react differently. Several catch blocks let each error type have its own message. A finally block then runs the same cleanup no matter which path you took.

The smallest working example

try {
    outcome = 'result:' + (a / b);
} catch (MathException zeroError) {
    outcome = 'error:zero';
} catch (NullPointerException nullError) {
    outcome = 'error:null';
} finally {
    outcome = outcome + ' (done)';
}

The try runs the risky work. One of the catch blocks runs if that work throws. The finally runs every time.

Name the parts

  • **try** holds the lines that might throw.
  • Each **catch** names one exception type. In Apex, a / 0 throws MathException; a null Integer in math throws NullPointerException.
  • **finally** always runs: on success, on a caught error, and even after an uncaught one on the way out.
  • Put specific types before general ones. A later catch (Exception e) would catch anything the earlier ones missed.

A common wrong version

try {
    outcome = 'result:' + (a / b);
    outcome = outcome + ' (done)';
} catch (Exception e) {
    outcome = 'error';
}

Two problems. Every error becomes the same error, so you cannot tell null from zero. And the (done) footer only appears on the happy path, because the appending line never runs when something throws.

The fix

Split the catches, and put the footer in finally:

} finally {
    outcome = outcome + ' (done)';
}

Now you try

Finish divide in the starter so the harness sees result:5 (done) for 10 / 2, error:zero (done) for 10 / 0 and error:null (done) for null inputs.

Learn more

The challenge

Write divide(Integer a, Integer b) so it returns a labelled result and always appends (done) from a finally block.

Examples:

  • divide(10, 2) builds result:5 (done)
  • divide(10, 0) builds error:zero (done)
  • divide(null, 2) builds error:null (done)

Requirements:

  1. divide(10, 2) should be result:5 (done).
  2. divide(10, 0) should be error:zero (done).
  3. divide(null, 2) should be error:null (done).
  4. divide(10, null) should be error:null (done).
  5. divide(9, 3) should be result:3 (done).

Starter code

String divide(Integer a, Integer b) {
    return '';
}

System.debug('10/2: ' + divide(10, 2));
System.debug('10/0: ' + divide(10, 0));

Related drills

Try this drill free

You write the Apex yourself. ApexSensei runs it and tells you what passed and what did not.

‹ Constructor chaining with this(...) · Static versus instance members ›