Fix exc_filters for mysql-python

Something changed in mysql-python / libmysqlclient or mysql and now
exceptions that used to be InternalError's have become OperationalError's.
Update filters accordingly to wrap those into oslo.db exceptions
properly.

OperationalError's are kind of special, as we re-raise them as is due
to historical reasons: we need to make sure that at least SAVEPOINT
errors are wrapped, as that's what oslo.db and neutron unit tests
expect.

Closes-Bug: #1630899

Change-Id: I39ea8c4a0dc9d43992f00da7b1ff502595b4dc13
This commit is contained in:
Roman Podoliaka 2016-11-03 15:20:50 +02:00
parent 628a1eec1e
commit 699933ca01
2 changed files with 17 additions and 2 deletions

View File

@ -252,6 +252,9 @@ def _check_constraint_error(
@filters("mysql", sqla_exc.InternalError,
r".*1091,.*Can't DROP '(?P<constraint>.+)'; "
"check that column/key exists")
@filters("mysql", sqla_exc.OperationalError,
r".*1091,.*Can't DROP '(?P<constraint>.+)'; "
"check that column/key exists")
@filters("mysql", sqla_exc.InternalError,
r".*1025,.*Error on rename of '.+/(?P<relation>.+)' to ")
def _check_constraint_non_existing(
@ -277,6 +280,8 @@ def _check_constraint_non_existing(
r".* no such table: (?P<table>.+)")
@filters("mysql", sqla_exc.InternalError,
r".*1051,.*Unknown table '(.+\.)?(?P<table>.+)'\"")
@filters("mysql", sqla_exc.OperationalError,
r".*1051,.*Unknown table '(.+\.)?(?P<table>.+)'\"")
@filters("postgresql", sqla_exc.ProgrammingError,
r".* table \"(?P<table>.+)\" does not exist")
def _check_table_non_existing(
@ -351,6 +356,14 @@ def _raise_data_error(error, match, engine_name, is_disconnect):
raise exception.DBDataError(error)
@filters("mysql", sqla_exc.OperationalError,
r".*\(1305,\s+\'SAVEPOINT\s+(.+)\s+does not exist\'\)")
def _raise_savepoints_as_dberrors(error, match, engine_name, is_disconnect):
# NOTE(rpodolyaka): this is a special case of an OperationalError that used
# to be an InternalError. It's expected to be wrapped into oslo.db error.
raise exception.DBError(error)
@filters("*", sqla_exc.OperationalError, r".*")
def _raise_operational_errors_directly_filter(operational_error,
match, engine_name,

View File

@ -306,7 +306,8 @@ class TestNonExistentConstraintMySQL(
# NOTE(jd) Cannot check precisely with assertInnerException since MySQL
# error are not the same depending on its version…
self.assertIsInstance(matched.inner_exception,
sqlalchemy.exc.InternalError)
(sqlalchemy.exc.InternalError,
sqlalchemy.exc.OperationalError))
if matched.table is not None:
self.assertEqual("resource_foo", matched.table)
if matched.constraint is not None:
@ -376,7 +377,8 @@ class TestNonExistentTableMySQL(
# NOTE(jd) Cannot check precisely with assertInnerException since MySQL
# error are not the same depending on its version…
self.assertIsInstance(matched.inner_exception,
sqlalchemy.exc.InternalError)
(sqlalchemy.exc.InternalError,
sqlalchemy.exc.OperationalError))
self.assertEqual("foo", matched.table)