What should a context manager do when the managed block raises an exception?
Quick answer
Put cleanup in a finally path so it runs when the managed block exits normally or raises. Then let the exception propagate unless your context manager is deliberately designed to suppress that specific exception. In a generator-based context manager, an exception is raised at the yield point; catching it without re-raising can suppress it, so distinguish handling or logging from cleanup. [S1]
The question, the details, the next step.
A practical checklist
Identify the cleanup action and place it on a path reached after both normal and exceptional exits.
For a generator-based manager, inspect what happens when an exception is raised at
yield.If an exception is caught only for logging or another side action, re-raise it unless suppression is deliberate. [S1]
List any exception types intentionally suppressed and record why callers should continue after them.
Consider separately what should happen if the cleanup action itself raises.
A few more useful answers
Does putting cleanup in `finally` mean the cleanup is guaranteed to succeed?
No. It provides a cleanup path that runs on exit, but the cleanup operation can still fail. Decide how that failure should be handled for your particular manager.
Does logging an exception automatically suppress it?
Logging alone does not require suppression. In a generator-based context manager, catch-and-log code should re-raise the exception when it is not meant to be suppressed. [S1]
Is exception suppression just another name for cleanup?
No. Cleanup concerns what happens on exit; suppression concerns whether a particular exception is allowed to propagate. They are separate decisions. [S1]
Sources
References used for this guide.
- [S1] contextlib — Utilities for with-statement contexts (Python 3.15.2) docs.python.org · Checked
