Error Handling in JavaScript

Introduction

When something goes wrong at runtime, JavaScript throws an error. Without handling, the exception stops the current call stack. try / catch / finally and custom Error types let you recover, log, and show friendly messages—essential for APIs, forms, and file I/O.

Prerequisites

Errors Stop Normal Flow

javascript
// Uncaught error halts script (in Node, exits with code)
function parsePort(text) {
  const port = Number(text);
  if (Number.isNaN(port)) {
    throw new Error("port must be a number");
  }
  return port;
}
 
try {
  console.log(parsePort("abc"));
} catch (err) {
  console.log("Caught:", err.message);
}

try / catch / finally

javascript
// finally always runs
let resource;
 
try {
  resource = { open: true };
  if (!resource.open) throw new Error("failed to open");
  console.log("working");
} catch (err) {
  console.log("Error:", err.message);
} finally {
  console.log("cleanup");
}

Built-in Error Types

javascript
// Common constructors
console.log(new SyntaxError("bad token").name);
console.log(new TypeError("not a function").name);
console.log(new RangeError("index out of range").name);

Check err.name or instanceof to branch handling.

Custom Errors

javascript
// Extend Error for domain cases
class ValidationError extends Error {
  constructor(field, message) {
    super(message);
    this.name = "ValidationError";
    this.field = field;
  }
}
 
function saveUser(email) {
  if (!email.includes("@")) {
    throw new ValidationError("email", "invalid email");
  }
  return { ok: true, email };
}
 
try {
  saveUser("bad");
} catch (err) {
  if (err instanceof ValidationError) {
    console.log(err.field, err.message);
  }
}

Re-throwing

javascript
// Log then propagate
async function loadConfig() {
  try {
    return JSON.parse("{ invalid");
  } catch (err) {
    console.error("parse failed", err.message);
    throw err;
  }
}

Mini Example: Safe JSON Parse Helper

javascript
function safeJsonParse(text, fallback = null) {
  try {
    return JSON.parse(text);
  } catch {
    return fallback;
  }
}
 
console.log(safeJsonParse('{"a":1}'));
console.log(safeJsonParse("not json", {}));

FAQ

catch (e) without type?

Valid—use when you do not need the error object.

Errors vs rejected Promises?

throw in sync code; Promise.reject in async—handled with .catch or try/catch around await.

Should I swallow errors?

Log or rethrow—empty catch blocks hide production bugs.

What comes next?

Typed arrays.