An exception is Python's way to stop normal flow when something goes wrong or cannot be completed.
The exception type tells you the category of problem: name lookup, wrong type, bad value, missing key, missing file, and more.
Use this page as a quick map from error type to cause and then open the full error guide when you need a detailed fix.
Most beginner errors come from syntax, indentation, names, types, values, indexes, keys, imports, and files.
| Exception | Usually Means |
|---|---|
| SyntaxError | Python cannot parse the code |
| IndentationError | Block spacing is missing or inconsistent |
| NameError | A name is not defined in the current scope |
| TypeError | An operation received the wrong type |
| ValueError | The type is right but the value is invalid |
| KeyError | A dictionary key is missing |
| IndexError | A sequence index is out of range |
| FileNotFoundError | The file path does not point to an existing file |
Raise an exception when your function cannot safely continue. Catch an exception only when you can recover or show a clearer message.
def divide(total, count):
if count == 0:
raise ValueError("count cannot be zero")
return total / count
try:
print(divide(10, 0))
except ValueError as error:
print(error)
count cannot be zero
The function raises a clear ValueError for an invalid value.
Catch the narrowest exception that represents the failure you can handle. Most application exceptions inherit from Exception. SystemExit, KeyboardInterrupt, and GeneratorExit inherit directly from BaseException so a broad except Exception block does not accidentally suppress normal process control.
Translate a low-level exception when callers need a domain-level contract, and preserve the cause with raise ... from error. A custom exception should identify a meaningful failure category, not merely rename every built-in exception. Put cleanup in a context manager or finally block so it runs on success, handled failure, and unexpected failure.
Do not catch an exception only to ignore it. Either recover, add useful context and re-raise, convert it at an abstraction boundary, or let it propagate. Bare except also catches process-control exceptions and should be reserved for the rare cleanup boundary that immediately re-raises.
class ConfigurationError(Exception):
pass
def read_port(raw: str) -> int:
try:
port = int(raw)
except ValueError as error:
raise ConfigurationError("PORT must be an integer") from error
if not 1 <= port <= 65535:
raise ConfigurationError("PORT must be between 1 and 65535")
return port
Callers receive one domain exception while the traceback retains the conversion failure that caused it.
Try this next
0 of 3 completed
No. Learn the common ones first and use the traceback plus this reference to identify the rest.
No. Some exceptions are expected signals, such as invalid user input or a missing optional file.
Catch specific expected exceptions and let unexpected programming bugs remain visible.
Explore 500+ free tutorials across 20+ languages and frameworks.