Your language · Python
Exceptions
Raising, catching and cleaning up after errors, and custom exceptions.
Learn: Exceptions in Python9 minute read
An exception is an object that Python raises when something goes wrong, such as a missing key, a bad number or a file that is not there. How you handle exceptions decides how clearly a test fails: a good framework turns "something broke" into a message that says what, where and why. Interviewers ask about the hierarchy, the full try statement, raising and chaining, and custom exceptions.
Step 1: the hierarchy
All exceptions inherit from BaseException. Under it sit SystemExit (raised by sys.exit), KeyboardInterrupt (Ctrl+C) and Exception, the parent of everything you normally catch.
ValueError means the right type with a wrong value, as in int("abc"), and TypeError means the wrong type, as in "1" + 1. LookupError is the parent of KeyError and IndexError. A failing assert (a check written in a test) raises AssertionError, which pytest (the usual Python test tool) reports as a test failure.
Python has no checked exceptions: nothing forces a function to declare or catch anything. Java has checked exceptions, which the compiler forces you to catch or declare. Document what a function raises in its docstring (the text in triple quotes under def) and test it with pytest.raises (a pytest helper that passes only when that exception is raised).
Step 2: try, except, else and finally
exceptblocks (Java calls themcatch) are tried top to bottom and the first match wins, so list specific types first. Python does not reject a general block placed first; the later blocks just never run.- A tuple catches several types:
except (KeyError, IndexError) as e:. elseruns only when thetryblock raised nothing.finallyalways runs, even afterreturn.- A bare
except:also catchesKeyboardInterruptandSystemExit. Writeexcept Exception:if you truly must catch broadly.
def parse(text):
try:
value = int(text)
except ValueError:
print("except", end=" ")
return None
else:
print("else", end=" ")
return value
finally:
print("finally", end=" ")
print(parse("42"))
print(parse("abc"))
def risky():
try:
return 1
finally:
return 2 # wins, and would hide errors: avoid
print(risky())
data = {"users": []}
try:
first = data["users"][0]
except (KeyError, IndexError) as e:
print("lookup failed:", type(e).__name__)
else finally 42 except finally None 2 lookup failed: IndexError
risky() returns 2, because a return in finally replaces the real result and can swallow an exception. Never return from finally.
Step 3: raise, raise from and custom exceptions
raise ValueError("timeout must be positive") raises an exception. Inside an except block, a bare raise raises the current exception again with its original traceback, for example after logging it. raise NewError(...) from e wraps a low-level error in a clearer one and keeps the original as its cause, so the traceback (the list of calls that led to the error) shows both.
For your own exceptions, subclass Exception, end the name with Error, and add fields if callers need details. One base class with specific subclasses lets callers catch the whole family at once.
import json
class FrameworkError(Exception):
pass
class DataFileError(FrameworkError):
def __init__(self, message, file=None):
super().__init__(message)
self.file = file
def load_users(path):
try:
with open(path, encoding="utf-8") as f:
return json.load(f)
except FileNotFoundError as e:
raise DataFileError(f"Cannot read {path}", file=path) from e
try:
load_users("missing_users.json")
except FrameworkError as e:
print(type(e).__name__, "-", e, "-", e.file)
print("cause:", type(e.__cause__).__name__)
DataFileError - Cannot read missing_users.json - missing_users.json cause: FileNotFoundError
Step 4: with statements
A with block guarantees clean-up, like Java's try-with-resources (a try that closes things for you). The object's __enter__ method runs at the start and __exit__ at the end, even if the block raises. Files, locks and pytest.raises all work this way, and a pytest fixture (a function that prepares things for a test) with yield gives the same guarantee for set-up and teardown (clean-up after the test).
How to answer in an interview
Start with the shape of the tree, then connect it to tests: "Everything comes from BaseException. I catch subclasses of Exception, never a bare except, so Ctrl+C still works. Python has no checked exceptions, so I document what a function raises and test it with pytest.raises." For custom exceptions, show a small class and a raise ... from e line.
Common mistakes
try: ... except: passaround a test step, which can turn a real failure into a pass.- Putting
except Exceptionbefore a more specific block. - Wrapping an error without
from e, which loses the original cause. - Returning from
finally. - Using exceptions for normal checks. To test that an element is absent, check that
find_elementsreturns an empty list.
Recap
BaseException is the root, and Exception is what you catch. There are no checked exceptions. else runs on success and finally always runs. Use raise ... from e to keep causes, subclass Exception for your own errors, and use with for clean-up.
10 questions0/10 solved
| Status | Question | Difficulty | Asked in |
|---|---|---|---|
| Not started | Where do exceptions sit in the hierarchy? | Easy | Asked in: Accenture, Infosys, TCS +1 |
| Not started | The Python exception hierarchy (and no checked exceptions) | Easy-Medium | Asked in: Accenture, Infosys, TCS +1 |
| Pro+ | raise, raise from, and the Python answer to throws | Easy | Asked in: Capgemini, Infosys, TCS +1 |
| Pro+ | try, except, else and finally: the rules | Medium | Asked in: Accenture, Capgemini, Cognizant +2 |
| Pro+ | except Exception before except ValueError | Medium | Asked in: Accenture, Capgemini, Cognizant +2 |
| Pro+ | return in try and finally | Medium | Asked in: Accenture, Capgemini, Cognizant +2 |
| Pro+ | Write and use a custom exception | Medium | Asked in: Wipro |
| Pro+ | What does a with statement guarantee? | Medium | Asked in: Infosys, TCS |
| Pro+ | Why is a bare except a problem? | Easy-Medium | Asked in: Accenture, Capgemini, Cognizant +2 |
| Pro+ | When does the else of a try run? | Easy-Medium | Asked in: Accenture, Capgemini, Cognizant +2 |
The first 2 questions of each topic are free. Pro+ opens every question.