In programming terms, throw is a generic term used to describe what a programming language will do when it encounters something that can’t be processed.
For example, when you call on an undefined function, JavaScript will throw an error:
myFn();
// Error: myFn is not defined
The complete technical term for the code above is that JavaScript throws an error: myFn is not defined.
Now JavaScript has a built-in throw
statement that allows you to trigger an error. By using throw
, you are technically throwing an exception.
throw expression;
Here’s an example of a throw
statement in action:
function doubleNumber(x) {
if (typeof x !== "Number" || isNaN(x)) {
throw "sorry, x is not a number";
}
console.log((x *= 2));
}
try {
let x = "X";
doubleNumber(x);
} catch (e) {
console.error(e);
// expected output: "sorry, x is not a number"
}
But keep in mind that you need to use the throw
statement in combination with try..catch
statement, because without the try..catch
statement, the exception you throw will not be caught by your code. The exception will be propagated up until it eventually gets caught by the default error reporting system that’s implemented by your JavaScript engine.
Let me give you an example. In the code below, the code will call on the getNumber
function, which will call the doubleNumber
function:
function getNumber() {
try {
let x = "X";
doubleNumber(x);
} catch (e) {
console.error(`doubleNumber error: ${e}`);
}
}
function doubleNumber(x) {
if (typeof x !== "Number" || isNaN(x)) {
throw "sorry, x is not a number";
}
console.log((x *= 2));
}
try {
getNumber();
} catch (e) {
console.error(`getNumber error: ${e}`);
}
console.log("The function is finished");
When you execute the code above, the doubleNumber
function will throw an exception, which will be caught by getNumber
function’s catch
statement:
> doubleNumber error: sorry, x is not a number
> "The function is finished"
Now let’s remove the try..catch
block from the getNumber
function:
function getNumber() {
let x = "X";
doubleNumber(x);
}
function doubleNumber(x) {
if (typeof x !== "Number" || isNaN(x)) {
throw "sorry, x is not a number";
}
console.log((x *= 2));
}
try {
getNumber();
} catch (e) {
console.error(`getNumber error: ${e}`);
}
console.log("The function is finished");
The doubleNumber
function still throws an exception, but getNumber
function doesn’t have a catch
statement, so the exception is propagated up to the code that calls on getNumber
:
> getNumber error: sorry, x is not a number
> "The function is finished"
Finally, let’s remove the last try..catch
block that surrounds getNumber()
call:
function getNumber() {
let x = "X";
doubleNumber(x);
}
function doubleNumber(x) {
if (typeof x !== "Number" || isNaN(x)) {
throw "sorry, x is not a number";
}
console.log((x *= 2));
}
getNumber();
console.log("The function is finished");
Without try..catch
block in your code, the exception will be propagated up again to the JavaScript code runner, and it will handle the exception. Usually, it will print the error message and stop the code execution. Here’s the result of the code above when executed with Node.js:
> throw "sorry, x is not a number";
^
> sorry, x is not a number
As you may notice, although the error is logged into the console, the log “The function is finished” is not printed to the console. This is because the general behavior of JavaScript is to throw an exception and stop the code execution.
By using the combination of throw
statement and try..catch
block, you will be able to generate a custom error message and change the behavior of JavaScript. This is useful to help you and other developers to maintain your codebase free from unexpected errors.
Throwing an object
Aside from throwing a string
or a number
value, you can also throw an object like this:
try {
throw new Error("sorry, x is not a number");
} catch (e) {
console.error(e);
// expected output: "Error: sorry, x is not a number"
}
The Error
object is just a JavaScript object with name
and message
property.