JavaScript: JavaScript Errors and Debugging

Last updated: 2026-10-13

Writing bug-free code is impossible — even the creator of JavaScript produced the typeof null === "object" bug in just 10 days. So learning to find bugs and handle errors is even more important than learning to write code.

Related BOM Methods:console.error() console.table() console.log() try...catch JSON.parse finally return error catch

1. Error Handling and Debugging

(1) Common Error Types

Error Type Cause Example
SyntaxError Invalid syntax if (true { — mismatched parentheses
ReferenceError Accessing a non-existent variable console.log(notExist)
TypeError Operating on the wrong type undefined.toString()
RangeError Value out of valid range new Array(-1)

SyntaxError is caught before code execution (parsing phase). The other three are runtime errors.

(2) try...catch...finally

Use try...catch to catch runtime errors and prevent your program from crashing:

HTML
<script>
try {
  const data = JSON.parse('{bad json}');
} catch (error) {
  console.log("Parse failed:", error.message);
} finally {
  console.log("Cleanup work");
}
</script>

The error object in catch has two commonly used properties:

(3) throw — Manually Throwing Errors

try...catch can only catch runtime errors, but business logic errors need to be thrown manually:

HTML
<script>
function setAge(age) {
  if (typeof age !== "number" || age < 0) {
    throw new Error("Age must be a positive number");
  }
  console.log("Age set to: " + age);
}

try {
  setAge(-5);
} catch (e) {
  console.log(e.message);
}
</script>

throw can throw any value, but using new Error() or its subclasses is recommended — they include stack trace information.

(4) Custom Error Messages

Use subclasses of Error or custom properties to provide richer error information:

HTML
<script>
class ValidationError extends Error {
  constructor(field, message) {
    super(message);
    this.name = "ValidationError";
    this.field = field;
  }
}

try {
  throw new ValidationError("email", "Invalid email format");
} catch (e) {
  console.log(e.name + " [" + e.field + "]: " + e.message);
}
</script>

(5) Browser DevTools (F12)

Panel Purpose
Console View logs, execute code, see errors
Sources Set breakpoints, step through code, inspect variables
Network Inspect network requests, response status, load times
Elements View/modify DOM and styles

Breakpoint debugging is the most powerful debugging technique: click a line number in the Sources panel to set a breakpoint, refresh the page, and the code pauses at that point — step through line by line, inspect variables, and examine the call stack.

(6) The console Family

Method Purpose
console.log() General output
console.warn() Warning (yellow)
console.error() Error (red)
console.table() Display arrays/objects as a table
console.time() / console.timeEnd() Timing
console.group() / console.groupEnd() Grouped output
console.clear() Clear the console

console.table is especially useful for displaying arrays of objects — far more readable than log.

(7) Debugging Tips


▶ Example: try/catch for JSON Parsing

▶ Try it Yourself

▶ Example: Custom Errors and Form Validation

▶ Try it Yourself

▶ Example: Error Types Quick Reference and console Methods

▶ Try it Yourself

Related BOM Methods:console.error() console.table() console.log() try...catch JSON.parse finally return error catch

❓ FAQ

Q Can try...catch catch SyntaxError?
A No. SyntaxError is thrown during the parsing phase before execution even begins, so the try block is never reached. However, if a SyntaxError occurs at runtime (e.g. JSON.parse fails, or new Function("bad syntax")), it can be caught.
Q When should I use finally?
A When you need cleanup operations to run regardless of whether an error occurred — closing files, releasing resources, hiding loading states. For most simple scenarios, catch alone is sufficient.
Q What's the difference between throw and return?
A return is for normal flow — the caller handles the returned value. throw is for abnormal flow — it skips subsequent code and walks up the call stack looking for a catch. Use throw for errors, return for normal results.

📖 Summary

📝 Exercises

  1. Write a function safeDivide(a, b) that uses try...catch to handle division by zero (hint: dividing by zero in JS doesn't throw — you need to check and throw yourself). Return the result or an error message.
  2. Write a function safeJSONParse(str) that parses a JSON string. On failure, return { success: false, error: <error message> }. On success, return { success: true, data: <parsed result> }.
  3. Write a function retry(fn, times): execute fn, and if it throws, retry up to times times. If all attempts fail, throw the last error. Implement with try...catch.
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏