Course progress0%
Course content

Module 1

Module 2

Module 3

Module 4

Module 5

Module 6

Module 7

Module 8

Module 9

Module 10

Module 11

Module 12

Module 13

Module 14

Module 15

Module 16

Module 17

Module 18

30 min

Exceptions and try / catch

Distinguish returned validation results from exceptions

By the end of this lesson

  • Distinguish returned validation results from exceptions
  • Handle failures at a boundary that can respond

A failure needs an explicit path

A lower-level calculation cannot produce a valid result for a negative price. It can throw an exception instead of returning a number. Its caller must know that contract.

function calculateSubtotal(price, quantity) {
  if (!Number.isFinite(price) || price < 0) {
    throw new Error("Invalid unit price");
  }
  if (!Number.isInteger(quantity) || quantity <= 0) {
    throw new Error("Invalid quantity");
  }
  return price * quantity;
}
let failureMessage = null;
try {
  calculateSubtotal(-2, 3);
} catch (error) {
  failureMessage = error.message;
}
console.assert(failureMessage === "Invalid unit price");
console.assert(calculateSubtotal(20, 3) === 60);

Throw stops the current normal path and transfers control to a matching catch, possibly in a caller. new Error creates an error with a message and stack information. The example controls the thrown value; arbitrary JavaScript can throw non-Error values, so do not assume every external failure has a message property.

Choose a contract deliberately

A validator returning a message is useful for expected user mistakes. A throwing calculation can be useful when callers must not proceed with invalid arguments. Neither style is universally correct. Do not mix them without documenting what each result means.

An optional finally block runs after the try/catch path, for cleanup. Avoid returning from finally because it can override the intended result or error.

Independent exercise

A catch block returns 0 for every failure. Explain why that is dangerous for a subtotal. Propose a response that does not confuse failure with a valid free order.

Correction

Zero is a legitimate amount, so this fallback hides the failure. At a display boundary, report that the quote could not be produced and include an appropriate explanation. At a lower layer, let the error reach a caller that can respond. Do not catch merely to suppress evidence.

Review

Try/catch does not validate rules automatically and does not catch a promise rejection that occurs later unless the promise is awaited in the protected asynchronous path. The asynchronous module will make that distinction concrete.

Lesson complete?

Your progress is saved on this device.