Error handling: try/catch/finally in JavaScript
Error Handling in JavaScript
try/catch/finally is the primary mechanism for handling runtime errors in JavaScript. It allows you to gracefully catch and recover from errors instead of crashing the application.
Basic Syntax
javascript
try {
// Code that might throw an error
const data = JSON.parse(invalidJson);
} catch (error) {
// Handle the error
console.error("Parsing failed:", error.message);
} finally {
// Always runs, regardless of error
console.log("Cleanup complete");
}The Error Object
javascript
try {
undefinedFunction();
} catch (error) {
console.log(error.name); // "ReferenceError"
console.log(error.message); // "undefinedFunction is not defined"
console.log(error.stack); // Full stack trace
}Built-in Error Types
| Error Type | When It Occurs |
|---|---|
Error | Generic error |
TypeError | Wrong type operation (null.prop) |
ReferenceError | Accessing undeclared variable |
SyntaxError | Invalid syntax (JSON.parse("{")) |
RangeError | Number out of range (new Array(-1)) |
URIError | Invalid URI function use |
Throwing Custom Errors
javascript
function divide(a, b) {
if (b === 0) {
throw new Error("Division by zero");
}
return a / b;
}
// Custom error class
class ValidationError extends Error {
constructor(field, message) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
function validateAge(age) {
if (typeof age !== "number") {
throw new ValidationError("age", "Age must be a number");
}
if (age < 0 || age > 150) {
throw new ValidationError("age", "Age must be between 0 and 150");
}
}Catching Specific Errors
javascript
try {
validateAge("abc");
} catch (error) {
if (error instanceof ValidationError) {
console.log(`Field: ${error.field}, Message: ${error.message}`);
} else if (error instanceof TypeError) {
console.log("Type error:", error.message);
} else {
throw error; // Re-throw unknown errors
}
}Async Error Handling
With async/await
javascript
async function fetchUser(id) {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
console.error("Fetch failed:", error.message);
return null;
}
}With Promises
javascript
fetch("/api/data")
.then(res => res.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));finally Block
finally always runs — even if catch has a return or throw:
javascript
function getData() {
let connection;
try {
connection = openConnection();
return connection.query("SELECT *");
} catch (error) {
return null;
} finally {
// Runs even after return!
connection?.close();
}
}Global Error Handling
javascript
// Browser — unhandled errors
window.addEventListener("error", (event) => {
console.error("Global error:", event.error);
});
// Unhandled promise rejections
window.addEventListener("unhandledrejection", (event) => {
console.error("Unhandled rejection:", event.reason);
event.preventDefault();
});Important:
Always handle errors in async code (both Promises and async/await). Create custom error classes for domain-specific errors. Use finally for cleanup (closing connections, removing loaders). Never silently swallow errors — at minimum, log them.
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.