Error Handling
try/catch vs try/except, custom errors, and error patterns
Introduction
In this lesson, you'll learn about error handling in JavaScript. Coming from Python, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In Python, you're familiar with try/catch vs try/except, custom errors, and error patterns.
JavaScript has its own approach to try/catch vs try/except, custom errors, and error patterns, which we'll explore step by step.
The JavaScript Way
Let's see how JavaScript handles this concept. Here's a typical example:
// try / catch / finally (no 'else' in JS)
try {
const result = riskyOperation();
console.log("Success:", result); // in try block
} catch (e) {
if (e instanceof TypeError) {
console.error("Type error:", e.message);
} else if (e instanceof RangeError) {
console.error("Range error:", e.message);
} else {
console.error("Unexpected:", e);
throw e; // re-throw
}
} finally {
cleanup(); // always runs
}
// Custom error class
class InsufficientFundsError extends Error {
constructor(amount, balance) {
super(`Need ${amount}, have ${balance}`);
this.name = "InsufficientFundsError";
this.amount = amount;
this.balance = balance;
}
}
// Throw
throw new InsufficientFundsError(100, 50);
// Async errors
async function fetchData() {
try {
const res = await fetch("/api/data");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (e) {
console.error("Fetch failed:", e);
throw e;
}
}Comparing to Python
Here's how you might have written similar code in Python:
# try / except / else / finally
try:
result = risky_operation()
except ValueError as e:
print(f"Bad value: {e}")
except (TypeError, KeyError) as e:
print(f"Type/Key error: {e}")
except Exception as e:
print(f"Unexpected: {e}")
raise # re-raise
else:
print("Success:", result) # runs if no exception
finally:
cleanup() # always runs
# Custom exception
class InsufficientFundsError(ValueError):
def __init__(self, amount, balance):
super().__init__(f"Need {amount}, have {balance}")
self.amount = amount
self.balance = balance
# Raise
raise InsufficientFundsError(100, 50)
# Context manager (cleanup)
with open("file.txt") as f:
data = f.read()You may be used to different syntax or behavior.
Python has 'else' clause (runs when no exception); JS does not
You may be used to different syntax or behavior.
Python 'except ExcType as e' vs JS 'catch (e)' — JS catches all types in one block
You may be used to different syntax or behavior.
JS uses instanceof inside catch for type discrimination
You may be used to different syntax or behavior.
Custom errors: both extend base class; JS requires setting this.name manually
You may be used to different syntax or behavior.
Python's context manager (with) auto-closes; JS uses try/finally for cleanup
Step-by-Step Breakdown
1. Basic try/catch
Python can have multiple except clauses for different types. JS has one catch block — use instanceof to check type.
try:
x = risky()
except ValueError:
handle_value_error()try {
const x = risky();
} catch (e) {
if (e instanceof RangeError) handleRangeError(e);
else throw e; // re-throw unknown errors
}2. Custom Error Classes
Both languages support custom exception hierarchies. In JS, set this.name so error messages show the class name.
class MyError(ValueError):
def __init__(self, msg):
super().__init__(msg)class MyError extends Error {
constructor(msg) {
super(msg);
this.name = "MyError"; // important!
}
}3. Re-throwing Errors
Both languages let you re-throw errors to propagate them up the call stack after logging or partial handling.
except Exception as e:
log(e)
raise # re-raise same exception} catch (e) {
log(e);
throw e; // re-throw — not throw new Error(e)
}4. Async Error Handling
async/await uses try/catch for async errors in both languages. Always handle rejections — unhandled rejections crash the process.
async def fetch():
try:
return await client.get(url)
except httpx.HTTPError as e:
raise RuntimeError(f"fetch failed: {e}")async function fetch() {
try {
const res = await axios.get(url);
return res.data;
} catch (e) {
throw new Error(`fetch failed: ${e.message}`);
}
}Common Mistakes
When coming from Python, developers often make these mistakes:
- Python has 'else' clause (runs when no exception); JS does not
- Python 'except ExcType as e' vs JS 'catch (e)' — JS catches all types in one block
- JS uses instanceof inside catch for type discrimination
Key Takeaways
- Python: except Type as e for each type; JS: one catch + instanceof checks
- Python has 'else' (success path) — in JS, put success code at end of try block
- Custom errors: extend Error; in JS set this.name for readable stack traces
- Re-throw with 'throw e' not 'throw new Error(e)' to preserve stack trace