Error Handling in JavaScript
Error Handling
While executing the JavaScript code, different errors may occur. These errors can be a syntax error, logical error, and runtime error. There are several ways of handling them:-
The try and catch:- The try statement is a block of code that lets us test a block of code for errors, while the catch statement is a block of code that lets us handle the error.
try {
expression;
}
catch(error) {
expression;
}
var a = 10;
var b = 20;
try {
console.log(a + b);
}
catch(error) {
console.log(error);
}
The throw:- The throw statement allows us to create a custom error.
var x;
try {
if(x == "") throw "Empty";
if(isNaN(x)) throw "Not a number";
}
catch(error) {
console.log(error);
}
The finally:- The finally statement is a block of code that lets us execute code, after try and catch, regardless of the result, which means finally block will always execute.
var x;
try {
if(x == "") throw "Empty";
if(isNaN(x)) throw "Not a number";
}
catch(error) {
console.log(error);
} finally {
console.log("Finally block will always execute!")
}
Error Types in JavaScript
JavaScript has several built-in error types. Understanding them helps you write more targeted error handling.
// ReferenceError - accessing undefined variable
try {
console.log(undeclaredVar);
} catch (e) {
console.log(e instanceof ReferenceError); // true
console.log(e.message); // undeclaredVar is not defined
}
// TypeError - wrong type operation
try {
null.property;
} catch (e) {
console.log(e instanceof TypeError); // true
}
// RangeError - value out of range
try {
new Array(-1);
} catch (e) {
console.log(e instanceof RangeError); // true
}
// SyntaxError - caught at parse time, not runtime
// eval('if ('); // SyntaxError
// Custom Error
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = 'ValidationError';
this.field = field;
}
}
try {
throw new ValidationError('Email is required', 'email');
} catch (e) {
console.log(e.name); // ValidationError
console.log(e.field); // email
console.log(e.message); // Email is required
}
Async Error Handling
When working with Promises and async/await, error handling requires special attention.
// Promise .catch()
fetch('/api/data')
.then(res => res.json())
.catch(err => console.error('Fetch failed:', err));
// async/await with try-catch
async function loadUser(id) {
try {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error(`HTTP error: ${res.status}`);
const user = await res.json();
return user;
} catch (err) {
console.error('Failed to load user:', err.message);
return null;
} finally {
console.log('Request complete');
}
}
// Global unhandled rejection handler
window.addEventListener('unhandledrejection', event => {
console.error('Unhandled promise rejection:', event.reason);
event.preventDefault();
});
- try/catch/finally is the standard way to handle runtime errors in JavaScript.
- The finally block always executes - use it for cleanup like closing connections.
- Use throw to create custom errors; you can throw strings, numbers, or Error objects.
- Extend the Error class to create custom error types with additional properties.
- For async/await, wrap await calls in try/catch to handle rejected promises.
- Use window.addEventListener("unhandledrejection") to catch unhandled promise rejections globally.