Intermediate
25 min read
Try, Catch, and Finally
By the end of this lesson, you'll be able to:
- Write a try/catch block to handle a runtime exception without crashing
- Explain what code inside finally guarantees
- Recognize the difference between an exception being thrown and being handled
Prerequisites: "ApexDoc and Documentation Standards"
Catching an exception
Decimal result;
try {
result = 10 / 0;
} catch (MathException e) {
System.debug('Caught a math error: ' + e.getMessage());
result = 0;
}
System.debug('Continuing normally: ' + result);
Decimal result;— declared outside thetryso it's still visible afterward.- (blank line)
try {—trymarks the block that might fail.result = 10 / 0;— withouttry/catch, this alone would throw aMathExceptionand immediately stop the whole transaction (as seen back in Module 8).} catch (MathException e) {—catchsteps in specifically for aMathException.System.debug('Caught a math error: ' + e.getMessage());— handles the problem instead of crashing.result = 0;— recovers with a sensible fallback value.}— closes thecatch.- (blank line)
System.debug('Continuing normally: ' + result);— this line still runs — execution continues normally after the caught error.
finally always runs
try {
Decimal result = 10 / 0;
} catch (MathException e) {
System.debug('Handled: ' + e.getMessage());
} finally {
System.debug('This always runs, error or not.');
}
try {— the risky block.Decimal result = 10 / 0;— throws aMathException.} catch (MathException e) {— catches it.System.debug('Handled: ' + e.getMessage());— handles it.} finally {—finallyruns whether thetrysucceeded, failed and got caught, or even failed in a way nothing caught.System.debug('This always runs, error or not.');— the right place for cleanup that must always happen regardless of outcome.}— closes thefinally.
A real business example: Order Processing
public String processOrder(Decimal orderTotal, Decimal discountPercent) {
try {
Decimal discount = orderTotal * (discountPercent / 100);
return 'Order total after discount: ' + (orderTotal - discount);
} catch (Exception e) {
System.debug('Failed to process order: ' + e.getMessage());
return 'Order could not be processed.';
} finally {
System.debug('Order processing attempt finished at ' + System.now());
}
}
public String processOrder(Decimal orderTotal, Decimal discountPercent) {— the method.try {— wraps the risky calculation.Decimal discount = orderTotal * (discountPercent / 100);— the calculation that might fail for any number of reasons.return 'Order total after discount: ' + (orderTotal - discount);— the success path.} catch (Exception e) {— a generic catch-all for whatever goes wrong.System.debug('Failed to process order: ' + e.getMessage());— logs the failure.return 'Order could not be processed.';— returns a sensible fallback message instead of crashing.} finally {— runs no matter which path above was taken.System.debug('Order processing attempt finished at ' + System.now());— logs that the attempt happened, successful or not, useful for auditing.}— closes thefinally.}— closes the method.
Exercise
Write a try/catch that attempts Decimal result = 20 / 0, catches MathException, debugs "Division failed", and uses finally to debug "Attempt complete".
Show hint
try { ... } catch (MathException e) { ... } finally { ... }
Try, Catch, and Finally Quiz
My Notes
Log in to keep private notes on this lesson.
Questions about this lesson
No questions yet — be the first to ask.
Log in to ask a question about this lesson.
Summary
try/catch lets code recover from a runtime error instead of crashing the whole transaction; finally guarantees a block of cleanup code runs no matter what happened in the try.