JavaScript Errors
Errors in JavaScript fall into two categories: errors that happen at parse time (before the code runs) and errors that happen at runtime (while the code is running). This page covers both, along with how to handle them gracefully.
Common error types
SyntaxError
A SyntaxError happens when JavaScript cannot parse your code. It usually means a typo, a missing bracket, or invalid syntax.
// Missing closing parenthesis
console.log('hello';
To fix: check that all brackets, braces, and parentheses are opened and closed correctly.
ReferenceError
A ReferenceError happens when you try to use a variable that does not exist.
console.log(myVariable); // ReferenceError: myVariable is not defined
To fix: check that the variable is declared and that you are not misspelling the name.
TypeError
A TypeError happens when you try to perform an operation on a value of the wrong type.
const name = null;
console.log(name.toUpperCase()); // TypeError: Cannot read properties of null
To fix: check what type of value you are working with before calling methods on it.
RangeError
A RangeError happens when a value is outside the allowed range.
new Array(-1); // RangeError: Invalid array length
(1.2345).toFixed(200); // RangeError: toFixed() digits argument must be between 0 and 100
URIError
A URIError happens when you pass a malformed URI to decodeURI() or decodeURIComponent().
decodeURI('%'); // URIError: URI malformed
Reading error messages
When an error occurs, the console shows you three things:
- The file and line number where the error happened.
- The type of error.
- A description of the error.
app.js:5
if (num > total;) {
^
SyntaxError: Unexpected token ';'
Here the error is in app.js at line 5, it is a SyntaxError, and the description tells you exactly what went wrong.
Debugging tips
- Run your code and read the error message before guessing at the problem.
- Use
console.log()to inspect values at different points if the error is not obvious. - Check MDN Web Docs for detailed explanations of specific JavaScript errors.
- Stack Overflow is useful for common errors; search the exact error message.
Constructing and throwing errors
You can create an error object with new Error() and throw it with the throw keyword.
function divide(a, b) {
if (b === 0) {
throw new Error('Cannot divide by zero');
}
return a / b;
}
console.log(divide(10, 2)); // 5
console.log(divide(10, 0)); // throws Error: Cannot divide by zero
throw stops execution immediately. Nothing after a throw runs unless the error is caught.
try/catch
Use try/catch to handle errors without crashing the program.
try {
const result = divide(10, 0);
console.log(result);
} catch (err) {
console.error('Something went wrong:', err.message);
}
// Prints: Something went wrong: Cannot divide by zero
// Execution continues here
The code in the try block runs normally. If an error is thrown, execution jumps to the catch block. Code after the try/catch continues running.
finally
The finally block always runs, whether the try succeeded or the catch ran.
async function loadData() {
showLoadingSpinner();
try {
const response = await fetch('/api/data');
if (!response.ok) {
throw new Error(`Server error: ${response.status}`);
}
const data = await response.json();
return data;
} catch (err) {
console.error('Failed to load data:', err.message);
} finally {
// always runs, hides the spinner whether we succeeded or failed
hideLoadingSpinner();
}
}
Use finally for cleanup that must happen regardless of the outcome, like hiding a loading indicator or closing a database connection.
Custom error classes
You can extend the built-in Error class to create your own error types. This makes it easier to handle different kinds of errors differently.
class ValidationError extends Error {
constructor(field, message) {
super(message);
this.name = 'ValidationError';
this.field = field;
}
}
function validateEmail(email) {
if (!email.includes('@')) {
throw new ValidationError('email', 'Email address is not valid');
}
}
try {
validateEmail('not-an-email');
} catch (err) {
if (err instanceof ValidationError) {
console.error(`Field "${err.field}" failed: ${err.message}`);
} else {
throw err; // re-throw unexpected errors
}
}
// Prints: Field "email" failed: Email address is not valid
Custom error classes let you check the type of error with instanceof and attach extra information (like which field failed).