Checking your session…
Module 05: Modules, File & Exception Handling

Error Handling

Level: 8 | Version: v1.0 | Author: Meptrasoft

Programs receive bad input, missing files, and failed network calls. Error handling lets a program respond to problems instead of crashing. This module uses a Payment Processing System as the running example.


Exceptions Basics

An exception is an error that occurs while a program is running. When an exception occurs and is not handled, the program stops and shows an error message called a traceback.

PYTHON
amount = 100
result = amount / 0

Output:

TEXT
ZeroDivisionError: division by zero

The program stops normal execution at that line. The lines after it do not run.

Error vs Exception

TEXT
Syntax Error → Code is written incorrectly (caught before running)
Exception    → Code is valid but fails while running

Syntax error (program does not even start):

PYTHON
if amount > 0
    print("Valid")

Exception (program starts, then fails):

PYTHON
amount = int("abc")   # ValueError at runtime

Common Exceptions

Exception When It Happens
ZeroDivisionError Dividing by zero
ValueError Right type, wrong value (int("abc"))
TypeError Wrong type used in an operation
IndexError List index out of range
KeyError Dictionary key does not exist
FileNotFoundError Opening a file that does not exist
NameError Using a variable that was never defined
AttributeError Using a method/attribute an object lacks
PYTHON
numbers = [10, 20, 30]
print(numbers[5])        # IndexError

student = {"name": "Arun"}
print(student["cgpa"])   # KeyError

Output:

TEXT
EXCEPTION → RUNTIME ERROR → PROGRAM STOPS (unless handled)

try / except Blocks

try blockrisky code Exception? No Yes elseruns if no error excepthandles the error finallyalways runs (cleanup) program continues
Control flow through try / except / else / finally. finally always runs, whether or not an exception occurred.

try

Put risky code inside a try block. Python watches it for exceptions.

PYTHON
try:
    amount = int(input("Enter amount: "))
    print("Amount:", amount)

If the risky line fails, Python stops running the try block and jumps to except instead of crashing.

except

The except block runs only when an exception occurs in the try block.

PYTHON
try:
    amount = int("abc")
except ValueError:
    print("Invalid amount entered")

Output:

TEXT
Invalid amount entered

The program continues normally after handling the error.

Catching Specific Exceptions

Handle different errors differently by naming each one:

PYTHON
    amount = int("abc")
try:
    result = amount / divisor
except ZeroDivisionError:
    print("Cannot divide by zero")
except ValueError:
    print("Invalid value")

Prefer specific exceptions over a bare except:, which hides real bugs.

Accessing the Error Message

Use as to capture the exception object.

PYTHON
try:
    amount = int("abc")
except ValueError as e:
    print("Error:", e)

Output:

TEXT
Error: invalid literal for int() with base 10: 'abc'

else

The else block runs only when no exception occurs in the try block.

PYTHON
try:
    amount = int("500")
except ValueError:
    print("Invalid amount")
else:
    print("Payment of", amount, "accepted")

Output:

TEXT
Payment of 500 accepted
TEXT
try succeeds → else runs
try fails     → except runs, else is skipped

finally

The finally block runs always — whether an exception occurred or not. Use it for cleanup such as closing files, closing connections, or ending a transaction.

PYTHON
connection_open = False

try:
    connection_open = True
    print("Processing payment")
except RuntimeError:
    print("Payment failed")
finally:
    if connection_open:
        print("Closing connection")

finally runs even if try succeeds, even if except runs, and even if the function returns from inside try.

Full Structure

PYTHON
try:
    # risky code
except SomeError:
    # runs if that error occurs
else:
    # runs if no error occurs
finally:
    # runs always
Block Runs When
try Always (contains the risky code)
except An exception occurs
else No exception occurs
finally Always (cleanup)

Raising & Custom

Raising Exceptions

Use raise to trigger an exception yourself — useful for rejecting invalid data.

PYTHON
def process_payment(amount):
    if amount <= 0:
        raise ValueError("Amount must be positive")
    print("Processing:", amount)

process_payment(-50)

Output:

TEXT
ValueError: Amount must be positive

raise stops the function immediately, exactly like a built-in exception. The caller can catch it:

PYTHON
def process_payment(amount):
try:
    process_payment(-50)
except ValueError as e:
    print("Rejected:", e)

Output:

TEXT
raise → TRIGGER AN EXCEPTION ON PURPOSE

Custom Exceptions

Create your own exception type by inheriting from Exception. This makes errors meaningful and specific to your application.

PYTHON
class PaymentError(Exception):
    pass

def process_payment(amount, balance):
    if amount > balance:
        raise PaymentError("Insufficient balance")
    print("Payment successful")

try:
    process_payment(1000, 500)
except PaymentError as e:
    print("Payment failed:", e)

Output:

TEXT
Payment failed: Insufficient balance

A custom exception reads clearly and can be caught separately from built-in errors.

TEXT
class MyError(Exception): pass  →  APP-SPECIFIC ERROR TYPE

assert Statement

assert checks that a condition is true. If it is false, Python raises an AssertionError. It is used to catch programming mistakes during development and testing.

PYTHON
def apply_discount(price, discount):
    assert discount >= 0, "Discount cannot be negative"
    return price - discount

apply_discount(100, -10)

Output:

TEXT
AssertionError: Discount cannot be negative
TEXT
assert condition, "message"
condition True  → continue
condition False → AssertionError

Do not use assert for normal user-input validation — assertions can be disabled when Python runs optimized (python -O). Use raise for real validation, assert for internal sanity checks.

Complete Payment Processing Example

This combines every concept — validate with raise, a custom exception, and try / except / else / finally in one flow.

PYTHON
class PaymentError(Exception):
    pass

def process_payment(amount, balance):
    if amount <= 0:
        raise ValueError("Amount must be positive")
    if amount > balance:
        raise PaymentError("Insufficient balance")
    return balance - amount

def pay(amount, balance):
    try:
        new_balance = process_payment(amount, balance)
    except ValueError as e:
        print("Invalid payment:", e)
    except PaymentError as e:
        print("Payment failed:", e)
    else:
        print("Payment successful. New balance:", new_balance)
    finally:
        print("Transaction closed\n")

pay(500, 1000)    # success
pay(-50, 1000)    # invalid amount
pay(2000, 1000)   # insufficient balance

Output:

TEXT
Payment successful. New balance: 500
Transaction closed

Invalid payment: Amount must be positive
Transaction closed

Payment failed: Insufficient balance
Transaction closed

Flow for each call:

TEXT
process_payment()
   ↓
amount <= 0?      → raise ValueError  → except ValueError
amount > balance? → raise PaymentError → except PaymentError
otherwise         → return balance    → else block
                                        ↓
                                 finally always runs

Each error path is handled cleanly, and finally closes the transaction every time — success or failure.

Common Fresher Mistakes

Mistake Problem Correct Understanding
Using bare except: Hides real bugs Catch specific exceptions
Confusing syntax error and exception Different stages Syntax = before run, exception = at run
Expecting else to run after an error else runs only on success Use except for the error path
Forgetting finally always runs Cleanup skipped Put cleanup in finally
Using assert for user validation Assertions can be disabled Use raise for real validation
Catching an exception but ignoring it (pass) Errors silently swallowed Log or handle it meaningfully

Placement Quick Points

  • An exception is a runtime error; unhandled, it stops normal program execution.
  • A syntax error is caught before running; an exception occurs while running.
  • try holds risky code; except handles the error.
  • Catch specific exceptions, not a bare except:.
  • else runs only when no exception occurs.
  • finally always runs — used for cleanup.
  • raise triggers an exception on purpose.
  • Custom exceptions inherit from Exception.
  • assert checks internal assumptions and raises AssertionError on failure.
  • Use raise for validation; use assert for development-time checks.

Interview Questions

What is an exception?
An error that occurs while a program is running.
What is the difference between a syntax error and an exception?
A syntax error is detected before the program runs. An exception occurs during execution.
What is the purpose of try and except?
try holds code that might fail; except handles the error if it occurs.
When does the else block run?
Only when no exception occurs in the try block.
When does the finally block run?
Always — whether or not an exception occurred.
What does raise do?
It triggers an exception intentionally.
How do you create a custom exception?
Define a class that inherits from Exception.
What does assert do?
It checks a condition and raises AssertionError if the condition is false.
What is the difference between assert and raise?
assert is for development-time checks and can be disabled. raise is for real error handling and always runs.
Why avoid a bare except:?
It catches every error, including bugs, and hides real problems.

Practice

  1. Trigger and read a ZeroDivisionError.
  2. Handle a ValueError from int("abc") using try/except.
  3. Catch two different exceptions with separate except blocks.
  4. Print the error message using except ... as e.
  5. Add an else block that runs on success.
  6. Add a finally block for cleanup.
  7. Raise a ValueError for a negative payment amount.
  8. Catch the raised ValueError in the caller.
  9. Create a PaymentError custom exception and raise it for insufficient balance.
  10. Use assert to check that a discount is not negative.
  11. Explain the difference between assert and raise.
  12. Predict the output:
PYTHON
try:
    print(10 / 2)
except ZeroDivisionError:
    print("Error")
else:
    print("No error")
finally:
    print("Done")
  1. Find the mistake:
PYTHON
try:
    amount = int("abc")
except:
    pass

End of Level 8