Exception Handling in Python


Exceptions are the run time errors. Here is the detail concept related to exception handling in python

Purpose:

The main purpose of handling exception in python are:

  • Prevents program crashes when unexpected occurrences (exceptions) arise.
  • Enables graceful program recovery or user-friendly error reporting.

Key Concepts:

Following are the key concepts and keywords used to handle runtime errors in python programming: 

  • try block: Contains code susceptible to exceptions.
  • except block: Handles specific exceptions, or all with except:.
  • else block: Executes if no exception occurs in the try block.
  • finally block: Always executes, regardless of exceptions.

Common Exceptions:

Following are the most commonly occurring runtime errors: 

  • ZeroDivisionError: Division by zero.
  • TypeError: Incorrect operand type for an operation.
  • NameError: Undefined variable or function name.
  • IndexError: Index out of bounds for a list, string, or other sequence.
  • ValueError: Invalid value for a function or operation.
  • KeyError: Key not found in a dictionary.
  • FileNotFoundError: Attempt to open a non-existent file.
  • KeyboardInterrupt: User presses Ctrl+C.

Best Practices:

Following are the best practices one need to follow while handling exception in program:

  • Specific Exception Handling: Use specific except blocks to handle different exception types and provide tailored responses.
  • Handle Common Exceptions: Anticipate potential errors and include appropriate exceptions blocks.
  • Don't Overuse except: Be mindful not to catch too many exceptions, as it can mask unexpected issues.
  • Log Exceptions: Consider using logging or alternative methods to record exception details for debugging and analysis.
  • Provide Informative Error Messages: Offer meaningful messages to users or administrators except blocks.
  • Test Thoroughly: Write comprehensive unit tests to cover various code paths and exception scenarios.

Key Concepts in Python Exception Handling:

1. try block:

  • Marks the code you expect might raise exceptions.

Example:

value = input("Enter a number: ")
try:
    number = int(value)
except ValueError:
    print("Invalid input: Please enter a number.")

Output:

Enter a number: aa
Invalid input: Please enter a number.

Explanation: The try block attempts to convert the user's input (value) to an integer (number).

2. except block:

  • Handles specific exceptions raised within the try block.
  • You can have multiple except blocks for different exceptions.

Example :

value = input("Enter a number: ")
try:
    number = int(value)
except ValueError:
    print("Invalid input: Please enter a number.")
except:  # General exception handler (use with caution)
    print("An unexpected error occurred.")

Output:

Enter a number: abcd
Invalid input: Please enter a number.

Explanation: The first except handles ValueError for invalid input. The second except (use cautiously) catches other unexpected exceptions.

3. else block:

  • Executes only if no exceptions occur in the try block.
  • Optional, often used for code that should run when everything goes well.

Example :

value = input("Enter a number: ")
try:
    number = int(value)
except ValueError:
    print("An unexpected error occurred.")
else:
    print("You entered:", number)

Output:

Enter a number: 10
You entered: 10

Explanation: The else block prints the converted number if no exceptions occur.

4. finally block:

  • Always executes, regardless of exceptions.
  • Useful for cleanup tasks like closing resources or logging errors.

Example:

try:
    # Code that may raise an exception
    result = 10 / 0  # This will raise a ZeroDivisionError
except ZeroDivisionError:
    print("Error: Division by zero!")
finally:
    # Code that should be executed regardless of whether an exception occurred
    print("This will always execute, regardless of exceptions.")

Output:

Error: Division by zero!
This will always execute, regardless of exceptions.

Explanation: The finally block ensures cleanup happens even if there are errors.

Raising Exceptions:

  • Signal errors or invalid conditions using raise.

Example:

try:
    # Code that may raise an exception
    x = int(input("Enter a number greater than 10: "))
    if x <= 10:
        raise ValueError("Number must be greater than 10")
except ValueError as ve:
    print("Error:", ve)
finally:
    # Code that should be executed regardless of whether an exception occurred
    print("This will always execute, regardless of exceptions.")

Output:

Enter a number greater than 10: 7
Error: Number must be greater than 10
This will always execute, regardless of exceptions.