summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Podoliaka <rpodolyaka@mirantis.com>2016-11-03 15:20:50 +0200
committerRoman Podoliaka <rpodolyaka@mirantis.com>2016-11-03 15:28:31 +0200
commit699933ca01884efe39cfed44946c3d570b5ebbfe (patch)
tree1298d3061833d8e07c5caf173bbb064201b891df
parent628a1eec1e1dd0f857a670aa89bbcb9c02b92627 (diff)
downloadoslo-db-699933ca01884efe39cfed44946c3d570b5ebbfe.tar.gz
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
-rw-r--r--oslo_db/sqlalchemy/exc_filters.py13
-rw-r--r--oslo_db/tests/sqlalchemy/test_exc_filters.py6
2 files changed, 17 insertions, 2 deletions
diff --git a/oslo_db/sqlalchemy/exc_filters.py b/oslo_db/sqlalchemy/exc_filters.py
index 38e759d..157dfd0 100644
--- a/oslo_db/sqlalchemy/exc_filters.py
+++ b/oslo_db/sqlalchemy/exc_filters.py
@@ -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,
diff --git a/oslo_db/tests/sqlalchemy/test_exc_filters.py b/oslo_db/tests/sqlalchemy/test_exc_filters.py
index 98dd569..5f1c113 100644
--- a/oslo_db/tests/sqlalchemy/test_exc_filters.py
+++ b/oslo_db/tests/sqlalchemy/test_exc_filters.py
@@ -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)