Implement a Context Manager That Suppresses Exceptions in Python
Shows how to write a custom context manager that catches specified exceptions and optionally re-raises others, plus the stdlib contextlib.suppress alternative.
Python code
31 linesimport contextlib
class SuppressExceptions:
def __init__(self, *exceptions):
self.exceptions = exceptions
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is None:
return False
if not self.exceptions or exc_type in self.exceptions:
print(f"Suppressed: {exc_type.__name__}: {exc_val}")
return True
return False
if __name__ == "__main__":
with SuppressExceptions(ValueError, TypeError):
result = int("not_a_number")
print("This line won't execute")
with SuppressExceptions(ValueError):
raise TypeError("This won't be suppressed")
with contextlib.suppress(ZeroDivisionError):
x = 1 / 0
print("This line won't execute either")
print("Program completed successfully")
Output
Suppressed: ValueError: invalid literal for int() with base 10: 'not_a_number'
Program completed successfully
How it works
The __exit__ method receives the exception type, value, and traceback when an exception occurs inside the with block. Returning True tells Python to suppress the exception; returning False or None lets it propagate. The custom class checks whether the raised exception type is in its allowlist and only suppresses those. The standard library's contextlib.suppress provides the same behavior with less code, making it ideal for simple cases. Both approaches ensure the rest of the program continues after a suppressed exception.
Common mistakes
- Forgetting to return `True` from `__exit__` to actually suppress the exception
- Not handling `exc_type is None` (no exception raised) and returning `False`
- Checking subclasses instead of exact types — the `in` check won't match subclasses
- Using a bare `except` with `contextlib.suppress()` which suppresses everything unintentionally
Variations
- Use `contextlib.suppress(ValueError, TypeError)` for a one-liner suppression.
- Use a decorator like `@contextmanager` to write a generator-based context manager.
Real-world use cases
- Wrapping legacy code that raises expected exceptions, logging them but continuing the application flow.
- Ignoring specific failures during cleanup tasks, like deleting temporary files that may already be gone.
- Suppressing non-critical errors in batch processing loops so one bad record doesn't abort the whole job.
Sponsored
More from Errors & debugging
- Catch RecursionError and Fail Gracefully in Python easy
- Catch ValueError and print friendly message in Python easy
- Collect Multiple Validation Errors in Python Before Raising medium
- Handle ValueError and ZeroDivisionError in Python with try except easy
- How to Add a Correlation ID to Logging Records in Python medium
- How to Assert Preconditions with Descriptive Messages in Python easy
Keep learning
Related tutorials and quizzes for this topic.