Skip to main content

Command Palette

Search for a command to run...

Error Handling in JavaScript: Try, Catch Finally

What Are Errors in JavaScript?

Updated
4 min readView as Markdown
Error Handling in JavaScript: Try, Catch Finally
T

MERN Stack developer focused on building real-world web applications. Currently exploring Generative AI and modern backend practices. I write about what I learn, build, and break along the way.

You're fully geared in BGMI Level 3 helmet, M416, full ammo. You push a building confidently. But the moment you enter an enemy is already there, your game lags, and you go down.

You didn't expect it. But a good player always has a plan for when things go wrong.

Your JavaScript code needs the same mindset. Things will fail API calls timeout, users enter wrong data, servers crash. Error handling is how your code survives those moments instead of breaking completely.

What Are Errors in JavaScript?

Errors are problems that occur while your code is running. JavaScript has several built-in error types:

SyntaxError = You wrote something JavaScript can't understand

// Missing closing bracket
if (true {
  console.log('oops'); // SyntaxError
}

ReferenceError = You used a variable that doesn't exist

console.log(playerName); // ReferenceError: playerName is not defined

TypeError = You used something in the wrong way

const player = null;
console.log(player.name); // TypeError: Cannot read properties of null

RangeError = A value is outside the allowed range

const arr = new Array(-1); // RangeError: Invalid array length

The try and catch Block

try wraps the code that might fail. catch handles it when it does.

try {
  // code that might throw an error
} catch (error) {
  // handle the error here
}

Example:

You push a building (try). There's an enemy inside and you go down (error). Instead of rage-quitting (app crash), you respawn at spawn island (catch) and re-enter the match. The game continues.

function getPlayerStats(player) {
  try {
    console.log(player.name.toUpperCase()); // what if player is null?
  } catch (error) {
    console.log('Could not load player stats:', error.message);
  }
}

getPlayerStats(null);
// Output: Could not load player stats: Cannot read properties of null

Without the try/catch, this would crash your entire program. With it, you handle the failure gracefully and keep going.

The finally Block

finally always runs whether an error happened or not. It's the code that must execute no matter what.

async function lootBuilding() {
  try {
    const loot = await fetchLoot();
    console.log('Looted:', loot);
  } catch (error) {
    console.log('Loot failed:', error.message);
  } finally {
    console.log('Running to safe zone...'); // always runs
  }
}

Common real-world uses for finally:

  • Hiding a loading spinner after a fetch call

  • Closing a database connection

  • Unlocking a UI button after form submission

Throwing Custom Errors

Sometimes JavaScript doesn't throw an error automatically but you want to throw one based on your own logic. Use the throw keyword.

Example: You try to fire but your weapon slot is empty. The game doesn't silently let you pull the trigger it throws a message: "No weapon equipped!" That's manual throwing. You define what counts as an error in your own logic.

function equipWeapon(weapon) {
  if (!weapon) {
    throw new Error('No weapon selected!');
  }
  console.log('Equipped:', weapon);
}

try {
  equipWeapon(null);
} catch (error) {
  console.log('Equipment failed:', error.message);
  // Equipment failed: No weapon selected!
}

Why Error Handling Matters

Bad error handling looks like this:

// No handling — crashes the whole app
const data = await fetchPlayerData();
console.log(data.stats.kills);

Good error handling looks like this:

// Graceful failure — app stays alive
try {
  const data = await fetchPlayerData();
  console.log(data.stats.kills);
} catch (error) {
  console.log('Could not load stats. Please try again.');
}

The difference from a user perspective:

Bad → White screen, frozen app, confused user Good → Friendly message, app keeps working, user knows what happened

Three real benefits of proper error handling:

  1. Graceful Failure — Your app doesn't crash. It degrades gracefully and shows the user something useful instead of a broken screen.

  2. Easier Debugging — error.message and error.stack tell you exactly what went wrong and where. Without catching errors, they can fail silently or show unhelpful messages.

  3. Better User Experience — Users see helpful messages like "Server is down, try again in a moment" instead of a frozen screen with no explanation.

Final Thoughts

  • try → Attempt the risky code

  • catch → React when it fails — don't let the app crash

  • finally → Always clean up, no matter what happened

  • throw → Manually trigger an error when your own logic requires it

  • Custom errors → Different problems deserve different handling

Just like in BGMI, things will go wrong. A good player has a plan. A good developer writes error handling.

Your code won't always chicken dinner. But with proper error handling, it'll never rage quit either.

JavaScript for Builders - The Tejas Dev Series

Part 12 of 25

JavaScript is easy to start but hard to truly understand. Most developers learn syntax. Few understand how it actually works. This series is my structured journey into mastering JavaScript fundamentals — explained with clarity, visual mental models, and real debugging insights. No shortcuts. No surface-level tutorials. We break down: How JavaScript executes code Scope, memory, and references Execution context & call stack Shallow vs deep copy ES6+ features that actually matter Common beginner traps Each article follows a clear structure: Confusion → Deep Breakdown → Visual Explanation → Real Use Case → Clear Takeaway. If you're a self-taught or bootcamp developer who wants clarity instead of copy-paste coding this series is built for you. Welcome to JavaScript for Builders. — Tejas Dev

Up next

JavaScript DOM Events Explained: Capturing, Target & Bubbling Phase for Beginners

Every click travels through the DOM here's exactly how it works and why it matters.