JavaScript programs sometimes encounter unexpected situations—such as undefined functions or invalid input—so the language provides mechanisms to detect, handle, and even throw custom errors. Error handling lets you gracefully manage issues at runtime, preventing crashes and enabling your code to respond or recover.
In JavaScript, you can use try
and catch
to safely run code that might fail, finally
to execute cleanup actions regardless of success, and throw
to create custom errors yourself. Beyond that, nested structures and async functions support structured error control. This article walks you through each feature with spirited examples that bring the ideas to life.
Using try
and catch
You begin error handling with a try
block where you place code that might fail. If an error occurs inside the try
, control immediately jumps to the catch
block, giving you access to the error and a chance to handle it.
Imagine a magical function castSpell()
that may not exist yet. Here’s how you might handle its invocation:
<!DOCTYPE html>
<html>
<head>
<title>Try Catch Example</title>
</head>
<body>
<script>
try {
castSpell('disappearify');
} catch (error) {
console.log('That spell failed:', error.message);
}
</script>
</body>
</html>
In this example, calling castSpell('disappearify')
causes an error—but our code catches it. The catch
prints a playful message along with the error’s message, preventing your script from crashing.
Using the finally
Block
After running code in try
or handling an error in catch
, finally
ensures that important cleanup always happens—regardless of whether an error occurred.
Picture opening a mystical chest with a trap:
<!DOCTYPE html>
<html>
<head>
<title>Finally Example</title>
</head>
<body>
<script>
function closeChest() {
console.log('Closing chest...');
}
try {
openChest();
grabTreasure();
} catch (error) {
console.log('Oops, trap triggered!');
} finally {
closeChest();
}
</script>
</body>
</html>
Here, closeChest()
executes no matter what happened in try
. It ensures that the chest is always closed, even if grabbing the treasure fails or triggers an exception.
Throwing Custom Errors with throw
JavaScript lets you create your own errors using throw new Error()
. This is ideal when running custom logic that fails due to application-specific conditions.
Consider a magical world where equipping a “Cursed Sword” is forbidden:
<!DOCTYPE html>
<html>
<head>
<title>Throw Example</title>
</head>
<body>
<script>
function equipItem(item) {
if (item === 'Cursed Sword') {
throw new Error('This item is cursed!');
}
console.log('You have equipped the', item);
}
try {
equipItem('Cursed Sword');
} catch (error) {
console.log('Cannot equip:', error.message);
}
</script>
</body>
</html>
If you try to equip the forbidden item, throw
creates a new error and catch
handles the message, giving the user feedback about why the action failed.
Nested Try‑Catch Blocks
Sometimes your code has multiple layers of operations, each of which may fail. Nested try
blocks let you manage errors specifically at different levels.
Here’s a dungeon explorer scenario:
<!DOCTYPE html>
<html>
<head>
<title>Nested Try Example</title>
</head>
<body>
<script>
try {
enterRoom('north');
try {
openDoor('wooden');
} catch (doorError) {
console.log('Wooden door jammed:', doorError.message);
}
enterRoom('east');
} catch (roomError) {
console.log('Failed to enter room:', roomError.message);
}
</script>
</body>
</html>
The inner catch
handles door-related problems, while the outer block catches broader room-access issues. This approach helps separate and handle errors at the right level.
Accessing Error Properties
When an error is caught, the catch parameter holds an Error object. You can inspect its properties like name
, message
, and stack
for more details.
Below is an example of trying to read from a scroll that might be missing, and logging detailed error info:
<!DOCTYPE html>
<html>
<head>
<title>Error Object Example</title>
</head>
<body>
<script>
try {
readScroll(null);
} catch (e) {
console.log('Name:', e.name);
console.log('Message:', e.message);
console.log('Stack trace:', e.stack);
}
</script>
</body>
</html>
This code prints the error’s name (e.g. "ReferenceError"
), the message, and the stack trace, giving insight into what went wrong and where.
Handling Errors in Functions
Functions often need internal error management and return values upon failure. Throwing and catching inside functions makes them safer to call.
Imagine brewing a potion with the wrong ingredient:
<!DOCTYPE html>
<html>
<head>
<title>Function Error Example</title>
</head>
<body>
<script>
function brewPotion(ingredient) {
if (ingredient !== 'unicorn hair') {
throw new Error('Potion failed. Wrong ingredient!');
}
return 'Potion brewed!';
}
try {
const result = brewPotion('goblin toe');
console.log(result);
} catch (error) {
console.log('Error while brewing:', error.message);
}
</script>
</body>
</html>
The function throws if the wrong ingredient is given. The try
around it catches the error and logs it, keeping the code flow intact.
Handling Errors in Asynchronous Code
You can also use try...catch
inside async
functions to handle errors that occur during await
operations.
Here’s a mystical summoning example:
<!DOCTYPE html>
<html>
<head>
<title>Async Error Example</title>
</head>
<body>
<script>
async function summonFamiliar(name) {
if (name !== 'Raven') throw new Error('Only Ravens respond to the call!');
return 'Raven has arrived!';
}
(async () => {
try {
const result = await summonFamiliar('Owl');
console.log(result);
} catch (e) {
console.log('Summoning failed:', e.message);
}
})();
</script>
</body>
</html>
Using async/await
, we can await a function that may throw an error and catch it gracefully, just like with synchronous code.
Conclusion
You’ve now seen how to handle runtime errors in JavaScript using try
, catch
, finally
, and throw
. You experienced nested error blocks, custom error throwing, asynchronous error handling, and inspecting error details. With these tools, you can control the flow of your code and respond creatively whenever something unexpected happens.
References
If you’re curious to explore further or want to double-check what you’ve learned, these trusted documentation pages offer more detailed explanations and examples:
- MDN Web Docs: try…catch
In-depth guide to the syntax and behavior oftry
,catch
, andfinally
. - MDN Web Docs: Error object
Overview of the Error object and its useful properties. - W3Schools: JavaScript Errors
Beginner-friendly explanation of error types and catching them.