Error Handling and Exceptions in Python - Interview Questions and Answers

Exception handling is a mechanism in Python that allows a program to handle runtime errors (exceptions) gracefully using try-except blocks instead of crashing.

try:
    # Code that may raise an exception
except ExceptionType:
    # Code to handle the exception

 

The program will terminate with an error message if the exception is not caught.

Yes, by specifying multiple exception types as a tuple.

try:
    x = 1 / 0
except (ZeroDivisionError, ValueError) as e:
    print(f"Error: {e}")

 

Use except Exception:

try:
    x = 1 / 0
except Exception as e:
    print(f"An error occurred: {e}")

 

No, because it hides all errors, making debugging difficult. It's better to catch specific exceptions.

Use the raise keyword.

raise ValueError("Invalid input")

 

try-except is used for handling runtime exceptions, whereas if-else is used for checking conditions before execution.

try:
    print(10 / 0)
except ZeroDivisionError:
    print("Cannot divide by zero")

Answer:

Cannot divide by zero
 

Yes, the else block executes if no exception occurs.

try:
    print("No error")
except:
    print("Error occurred")
else:
    print("Executed successfully")

Output

No error  
Executed successfully

 

A user-defined exception created by subclassing Exception.

class MyError(Exception):
    pass

 

class MyError(Exception):
    def __init__(self, message):
        super().__init__(message)

 

raise MyError("Something went wrong")

 

Yes, but it's recommended to inherit from Exception to maintain best practices.

try:
    raise MyError("Custom error occurred")
except MyError as e:
    print(e)

 

Built-in exceptions cover common errors, while custom exceptions allow application-specific error handling.

Yes, multiple classes can be created for different error types.

Yes, for example, overriding __str__ for custom messages.

Custom exceptions provide clearer error messages and specific error handling.

The finally block ensures that code executes regardless of whether an exception occurs.

 

try:
    print(1 / 0)
except ZeroDivisionError:
    print("Handled error")
finally:
    print("This always runs")

 

Yes, finally executes before the program terminates.

Yes, but try is still required.

try:
    print("Try block")
finally:
    print("Finally block")

To release resources like closing files or database connections.

An assertion is a debugging aid that checks a condition using the assert statement.

assert condition, "Error message"

 

An AssertionError is raised.

x = 10
assert x > 5, "x is too small"
print("Passed")

Answers:

Passed

 

Run Python with the -O (optimize) flag:

python -O script.py

assert is for debugging; raise is for error handling.

Yes, using except AssertionError:.

Context managers (with statement) ensure resources are released properly.

try-finally ensures execution, while try-except-finally handles exceptions.

It overrides any previous exception.

If another exception is raised inside an except block, it will propagate unless caught by another try-except block.

Yes, you can have a try-except block inside another try-except block for more granular error handling.

try:
    try:
        x = 1 / 0
    except ZeroDivisionError:
        print("Inner except: Division by zero")
        raise ValueError("Raising new error")
except ValueError as e:
    print(f"Outer except: {e}")

Exception chaining allows linking exceptions using raise from.

try:
    x = 1 / 0
except ZeroDivisionError as e:
    raise ValueError("New error") from e

 

raise re-raises an exception, whereas raise from explicitly links a new exception to the original cause.

It re-raises the last caught exception.

try:
    x = 1 / 0
except ZeroDivisionError:
    print("Handling error")
    raise  # Re-raises the ZeroDivisionError

 

Use the logging module.

import logging

logging.basicConfig(level=logging.ERROR)
try:
    x = 1 / 0
except ZeroDivisionError as e:
    logging.error("An error occurred", exc_info=True)

 

Use separate except blocks.

try:
    x = int("abc")
except ValueError:
    print("Value error occurred")
except TypeError:
    print("Type error occurred")

 

  • sys.exit() terminates the program immediately.
  • Raising an exception allows it to be caught and handled.

Use exception.args.

try:
    raise ValueError("Invalid input", 400)
except ValueError as e:
    print(e.args)  # ('Invalid input', 400)

 

Closing a database connection regardless of errors.

import sqlite3
try:
    conn = sqlite3.connect('database.db')
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM users")
except Exception as e:
    print(f"Error: {e}")
finally:
    conn.close()

 

Use try-except-finally or a context manager.

try:
    with open("file.txt", "r") as f:
        data = f.read()
except FileNotFoundError:
    print("File not found")

 

Yes, using contextlib.suppress().

from contextlib import suppress

with suppress(ZeroDivisionError):
    x = 1 / 0  # No exception raised

 

The traceback module provides detailed error information.

import traceback

try:
    x = 1 / 0
except Exception as e:
    print(traceback.format_exc())

 

Using raise Exception("New message") from original_exception.

try:
    x = 1 / 0
except ZeroDivisionError as e:
    raise ValueError("Custom message") from e

 

  • Catch specific exceptions.
  • Use finally to clean up resources.
  • Avoid suppressing exceptions.
  • Use logging instead of print().
  • Use custom exceptions for clarity.
Share   Share