Because we caught the error, our program will not halt—we log the error and con‐
tinue. We may still be in trouble—if a valid email is required, our program might not
be able to meaningfully continue, but at least we can now handle the error more
gracefully.
Note that control shifts to the
catch
block as soon as an error occurs; that is, the
if
statement that follows the call to
validateEmail
won’t execute. You can have as many
statements as you wish inside the
try
block; the first one that results in an error will
transfer control to the
catch
block. If there are no errors, the
catch
block is not exe‐
cuted, and the program continues.
Throwing Errors
In our previous example, we used a
try...catch
statement to catch an error that
JavaScript itself generated (when we tried to call the
match
method of something
that’s not a string). You can also “throw” (or “raise”) errors yourself, which initiates
the exception handling mechanism.
Unlike other languages with exception handling, in JavaScript, you can throw any
value: a number or a string, or any other type. However, it’s conventional to throw an
instance of
Error
. Most
catch
blocks expect an instance of
Error
. Keep in mind that
you can’t always control where the errors you throw are caught (functions you write
might be used by another programmer, who would reasonbly expect any errors
thrown to be instances of
Error
).
For example, if you’re writing a bill-pay feature for a banking application, you might
throw an exception if the account balance can’t cover the bill (this is exceptional
because this situation should have been checked before bill pay was initiated):
function
billPay
(
amount
,
payee
,
account
) {
if
(
amount
>
account
.
balance
)
throw
new
Error
(
"insufficient funds"
);
account
.
transfer
(
payee
,
amount
);
}
When you call
throw
, the current function immediately stops executing (so, in our
example,
account.transfer
won’t get called, which is what we want).
Exception Handling and the Call Stack
A typical program will call functions, and those functions will in turn call other func‐
tions, and those functions even more functions, and so on. The JavaScript interpreter
has to keep track of all of this. If function
a
calls function
b
and function
b
calls func‐
tion
c
, when function
c
finishes, control is returned to function
b
, and when
b
fin‐
Throwing Errors | 171