Error handling in context managers

Peter Otten __peter__ at
Tue Jan 17 03:34:13 EST 2017

Gregory Ewing wrote:

> Israel Brewster wrote:
>> The problem is that, from time to time, I can't get a connection, the
>> result being that cursor is None,
> That's your problem right there -- you want a better-behaved
> version of psql_cursor().
> def get_psql_cursor():
>     c = psql_cursor()
>     if c is None:
>        raise CantGetAConnectionError()
>     return c
> with get_psql_cursor() as c:
>     ...

You still need to catch the error -- which leads to option (3) in my zoo, 
the only one that is actually usable. If one contextmanager cannot achieve 
what you want, use two:
$ cat
import sys
from contextlib import contextmanager

class NoConnection(Exception):

class Cursor:
    def execute(self, sql):
        print("EXECUTING", sql)

def cursor():
    if "--fail" in sys.argv:
        raise NoConnection
    yield Cursor()

def no_connection():
    except NoConnection:
        print("no connection")

with no_connection(), cursor() as cs:
    cs.execute("insert into...")
$ python3
EXECUTING insert into...
$ python3 --fail
no connection

If you want to ignore the no-connection case use 
contextlib.suppress(NoConnection) instead of the custom no_connection() 

More information about the Python-list mailing list