Exception Hierarchy in Python

Python tutorial · PySpark.in

What Actually Happens When an Exception Occurs?

  1. Python pauses execution where the error occurred
  2. It creates an exception object (e.g., ZeroDivisionError)
  3. It searches for an except block that matches
  4. If found then handler runs
  5. If not then program crashes

Basic Exception Handling Recap

Syntax:

```

Hide

try:

risky_code()

except ExceptionType:

handle_error()

```

1. The Exception Hierarchy in Python

All exceptions are derived from the base class:

2. Catching All Exceptions (Use Carefully)

```

try:

code()

except Exception as e:

print("Error:", e)

```

Note:

3. Custom Exception Classes

You can define your own exception type:

```

class AgeTooLowError(Exception):

pass

age = 15

if age < 18:

raise AgeTooLowError("Age must be 18 or above!")

```

Use custom exceptions when:

4. Logging Exceptions Instead of Printing

Printing errors is bad practice for real apps. Use the logging module:

```

import logging

logging.basicConfig(filename="errors.log", level=logging.ERROR)

try:

x = 10 / 0

except Exception as e:

logging.error("Error occurred: %s", e)

```

5. Using finally for Resource Cleanup 

finally always executes:

Example:

```

try:

f = open("data.txt")

print(f.read())

except FileNotFoundError:

print("File missing!")

finally:

print("Closing file.")

try:

f.close()

except:

pass

```

6. Using try with else

else runs only if no exception occurs.

```

try:

num = int(input("Enter: "))

except ValueError:

print("Invalid!")

else:

print("Success!")

```

7. Raising Exceptions with Custom Messages

```

x = -5

if x < 0:

raise ValueError("Number cannot be negative!")

```

Used for:

8. Exception Chaining (raise ... from ...)

Used for combining two exceptions.

```

try:

int("abc")

except ValueError as e:

raise TypeError("Type conversion failed!") from e

```

9. Context Managers & Exception Handling

with handles exceptions internally:

```

with open("file.txt") as f:

data = f.read()

```

10. Real-World Examples of Exception Handling

API Requests

```

Hide

import requests

try:

res = requests.get("https://api.github.com")

res.raise_for_status()

except requests.exceptions.RequestException as e:

print("API error:", e)

```

Database Connections

```

Hide

try:

conn = db.connect()

# operations

except db.Error as e:

print("DB Error")

finally:

conn.close()

```

User Input Validation

```

def get_age():

while True:

try:

age = int(input("Enter age: "))

return age

except ValueError:

print("Please enter a valid number!")

```

When NOT to Use Exception Handling


DO vs DON’T for Python Exception Handling

Category

✔ DO

❌ DON’T

Type of Exceptions

Catch specific exceptions (e.g., ValueError, FileNotFoundError)

Use bare except (except:) catching everything blindly

Code Structure

Keep try blocks small (only risky lines)

Put huge code blocks inside try, hiding real errors

Resource Management

Use finally to release resources (files, DB connections)

Forget to close resources → leads to memory leaks

Error Reporting

Log exceptions using the logging module

Print exceptions using print(), makes debugging hard

Exception Raising

Raise meaningful custom messages (raise ValueError("Invalid age"))

Raise exceptions without messages (raise ValueError)

Custom Exceptions

Create custom exception classes in big projects

Overuse built-in exceptions for all error types

Handling Logic

Handle exceptions you can actually recover from

Catch exceptions that you cannot fix

Debugging

Use traceback or structured logs

Hide exceptions silently or ignore them

Validation

Validate inputs before running risky code

Depend on try/except as a replacement for validation

Multiple Exceptions

Catch multiple exceptions using tuples

Write multiple except blocks for each tiny case

More Python tutorials

All tutorials · Try the free PySpark compiler · Practice challenges