Skip to main content
ThePythonBook/Assessment

Error Handling Assessment

Test your mastery of Python error handling: try-except blocks, custom exceptions, context managers, and defensive programming patterns.

Progress
850 XP0/10
#1Safe Division
Write Code

Write a function safe_divide(a, b) that returns the result of a / b. If b is zero, return the string "Cannot divide by zero". If either argument is not a number, return the string "Invalid input".

Loading editor...
#2Fix the Exception Hierarchy
Fix the Bug

The function below is supposed to catch ValueError and Exception separately, but the specific ValueError handler never runs. Fix the bug so that parse_int("abc") prints "Not a valid integer" and parse_int(None) prints "Unexpected error".

Loading editor...
#3Custom ValidationError
Write Code

Create a custom exception class ValidationError that inherits from ValueError. It should accept a field and message parameter and store them as attributes. Its string representation (__str__) should return "{field}: {message}". Then write a function validate_age(age) that raises ValidationError("age", "Must be between 0 and 150") if age is not in that range, otherwise returns age.

Loading editor...
#4Predict: Finally Always Runs
Predict Output

What does the following code print? Pay careful attention to the order of execution with try, except, and finally.

Loading editor...
#5Fix the Else Clause
Fix the Bug

The function below should print "Conversion successful: <number>" only when no error occurs, and "Invalid" when a ValueError is raised. Currently the success message prints even on error. Fix it using the else clause properly.

Loading editor...
#6Input Validator
Write Code

Write a function validate_username(username) that raises:

  • TypeError with message "Username must be a string" if username is not a string
  • ValueError with message "Username cannot be empty" if it is an empty string
  • ValueError with message "Username too long" if it is longer than 20 characters
  • Otherwise return the username stripped of leading/trailing whitespace.

    Loading editor...
    #7Predict: Exception Chaining
    Predict Output

    What does the following code print? Think about how raise ... from ... affects the exception chain.

    Loading editor...
    #8Refactor: Use a Context Manager
    Refactor

    Refactor the ManagedResource class below so it can be used as a context manager with with. The __enter__ method should call self.open() and return self. The __exit__ method should call self.close() and return False (do not suppress exceptions). Keep the existing open, close, and read methods unchanged.

    Loading editor...
    #9Refactor: Add Retry Logic
    Refactor

    Refactor the fetch_data function to include retry logic. Write a function retry(func, max_attempts=3) that:

  • Calls func() up to max_attempts times
  • If func() succeeds, return its result immediately
  • If func() raises a ConnectionError, print "Attempt <n> failed" and try again
  • If all attempts fail, raise the last ConnectionError
  • Keep fetch_data as-is (it is used by the test cases).

    Loading editor...
    #10Fix the Silent Failure
    Fix the Bug

    The function below silently swallows all errors with a bare except: pass. Fix it so that:

  • ZeroDivisionError prints "Error: division by zero"
  • TypeError prints "Error: invalid type"
  • All other exceptions are re-raised
  • The function should return the result on success, or None when a handled error occurs.

    Loading editor...