Python for JS Devs · Fundamentals

Exceptions & error handling

try/catch becomes try/except — but Python leans on exceptions far more than JS, and there's a cleaner cultural style around them.

Lesson 09Time ~12 min Win Catch a specific exception & raise a custom onePrereq Lesson 08

1 · try / except / else / finally

JavaScript
try {
  risky();
} catch (e) {
  if (e instanceof TypeError) {}
} finally {
  cleanup();
}
throw new Error("boom");
Python
try:
    risky()
except ValueError as e:     # catch a SPECIFIC type
    ...
else:                     # ran only if no exception
    ...
finally:
    cleanup()
raise ValueError("boom")   # `raise`, not `throw`

Differences worth noting:

2 · Catch narrowly — a bare except is a smell

Rule Never write a bare except: or except Exception: "just to be safe" — it swallows bugs, including ones you'd want to crash on. Catch the specific exception you can actually handle. If you must log-and-reraise, use raise with no argument to preserve the original traceback.
try:
    user = users[user_id]
except KeyError:
    logger.warning("missing user %s", user_id)
    raise                    # re-raise, keep the traceback

3 · Custom exceptions = subclass

Domain errors are just classes inheriting from Exception. This is exactly how you'll model API errors before mapping them to HTTP status codes in FastAPI (Lesson 15).

class UserNotFoundError(Exception):
    pass

def get_user(uid: str) -> dict:
    if uid not in db:
        raise UserNotFoundError(uid)
    return db[uid]
EAFP — a cultural shift Python favours "Easier to Ask Forgiveness than Permission": try the operation and catch the failure, rather than the JS-ish "Look Before You Leap" of checking everything first. E.g. try: d[k] except KeyError: is often preferred over pre-checking if k in d. Exceptions in Python are cheap and idiomatic — not the exceptional-only tool they are in JS.

🎯 Your win

In the REPL: define UserNotFoundError, write get_user against a small dict, then call it inside a try/except UserNotFoundError as e: and print a friendly message. Raising and catching your own exception type is the win — it's the exact pattern behind FastAPI error handling.

Check yourself

Q1. The keyword to signal an error in Python is:
raise SomeError(...) — Python uses raise, not throw.
Q2. Best practice when catching exceptions is to:
Catch the narrow type you can actually handle; a bare except hides real bugs.
Q3. A custom exception is created by:
Define class MyError(Exception): pass and raise it.
Primary source Python docs — Errors and Exceptions. The full model, including the built-in exception hierarchy.
💬 Ask your teacher: what's the difference between except (A, B) and exception groups? And when is EAFP the wrong call?