0

I have a django project, where multiple database backends are supported. I want a check (in order to print a sensible error message to user) what the error on a ordinary queryset operator is e.g. I want to catch cx_Oracle.DatabaseError and psycopg2.OperationalError etc. when the database host is unreachable or not running a database service at the port specified (or credentials are invalid etc.)

The problem is that in my code I don't know which backed is used and whether the modules are available.

I could do something like:

dberrors = list()
try:
   from psycopg2 import OperationalError
   dberrors.append(OperationalError)
except ImportError:
   pass
try:
   from cx_Oracle import DatabaseError:
   dberrors.append(DatabaseError)
except ImportError:
   pass
# and so on
databaseerrors = tuple(databaseerrors)

try:
   mymodels.Model.objects.filter()
except databaseerrors as e:
   logger.critical("Database host is not accepting connections")
   sys.exit(1)

... but is there a more idiomatic or pretty way?

Kimvais
  • 38,306
  • 16
  • 108
  • 142

1 Answers1

1

Seems like at very least you could do it in a loop ...

mod_errors = [
    ('psycopg', 'OperationalError'),
    ('cx_Oracle', 'DatabaseError'),
    # ... More here.
]

for mod, err in mod_errors:
    try:
        m = __import__(mod)
    except ImportError:
        continue

    dberrors.append(getattr(m, err)) 

databaseerrors = tuple(dberrors)
mgilson
  • 300,191
  • 65
  • 633
  • 696