Python for JS Devs · Fundamentals
try/catch becomes try/except — but Python leans on exceptions far more than JS, and there's a cleaner cultural style around them.
try {
risky();
} catch (e) {
if (e instanceof TypeError) {}
} finally {
cleanup();
}
throw new Error("boom");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:
except not catch; raise not throw.except clauses. Prefer specific types over a bare except:.else clause (runs when no exception fired) has no JS equivalent — handy for keeping the "happy path" out of the try.except is a smellexcept: 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
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]
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.
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.
raise SomeError(...) — Python uses raise, not throw.except hides real bugs.class MyError(Exception): pass and raise it.except (A, B) and exception groups? And when is EAFP the wrong call?