Python
exception handling
with statement
context managers
error catching

Catching an exception while using a Python 'with' statement

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Yes, you can catch exceptions while using a Python with statement. The usual way is to put the entire with block inside a try and except, just as you would for any other block of code.

The presence of with does not remove normal exception handling. What it changes is resource cleanup: the context manager's __exit__ method still runs when an exception happens, so files, locks, and similar resources can be released correctly.

Catch the Exception Around the with Block

This is the normal pattern:

python
1try:
2    with open("data.txt", "r", encoding="utf-8") as file:
3        content = file.read()
4        print(content)
5except FileNotFoundError:
6    print("The file does not exist.")
7except OSError as error:
8    print(f"File operation failed: {error}")

If an exception occurs while opening the file or while executing the code inside the with block, the except handler can catch it.

The important point is that cleanup still happens. If the file was opened successfully, Python will call the context manager's exit logic before control reaches the except block.

What the Context Manager Does on Exception

A with statement uses a context manager, which usually defines __enter__ and __exit__. If an exception occurs, Python calls __exit__(exc_type, exc_value, traceback).

That means a context manager can choose either to let the exception propagate or to suppress it.

Example:

python
1class DemoContext:
2    def __enter__(self):
3        print("enter")
4        return self
5
6    def __exit__(self, exc_type, exc_value, traceback):
7        print("exit")
8        return False
9
10try:
11    with DemoContext():
12        raise ValueError("boom")
13except ValueError as error:
14    print("caught:", error)

Because __exit__ returns False, the exception is not suppressed, so the outer except sees it.

Suppressing an Exception Inside the Context Manager

If __exit__ returns True, the exception is considered handled and will not propagate outward:

python
1class SuppressingContext:
2    def __enter__(self):
3        return self
4
5    def __exit__(self, exc_type, exc_value, traceback):
6        return exc_type is ValueError
7
8with SuppressingContext():
9    raise ValueError("hidden")
10
11print("program continues")

This is legal, but it should be used carefully. Silent suppression can make debugging much harder if it hides failures you actually needed to see.

Decide Where the Exception Should Be Handled

There are two separate design choices:

  • catch the exception outside the with block with try and except
  • handle or suppress it inside the context manager's __exit__

In most application code, the first option is clearer. Reserve exception suppression inside __exit__ for context managers whose explicit job is to absorb certain failures.

The with Statement Still Helps with Cleanup

Developers sometimes think a with statement and a try and except are competing techniques. They are not. They solve different problems:

  • 'with handles setup and cleanup'
  • 'try and except handle error control flow'

You often want both together. That is exactly why with open(...) inside try and except is so common.

Common Pitfalls

  • Assuming exceptions inside a with block cannot be caught normally.
  • Returning True from __exit__ accidentally and suppressing errors you needed to see.
  • Using with for cleanup but forgetting that opening the resource itself can also raise an exception.
  • Treating with as a replacement for try and except instead of a complement to it.

Summary

  • Catch exceptions around a with block with normal try and except syntax.
  • The context manager still runs its cleanup logic even when an exception occurs.
  • '__exit__ can inspect the exception and optionally suppress it by returning True.'
  • In most code, handling the exception outside the with block is the clearer approach.
  • 'with manages resources; try and except manage error handling.'

Course illustration
Course illustration

All Rights Reserved.