From 27013e87f53cccbfd2e203f065e416437ba08987 Mon Sep 17 00:00:00 2001 From: Mike Lundy Date: Fri, 2 Mar 2012 00:15:04 +0000 Subject: [PATCH] Fail gracefully when the db doesn't speak unicode When sqlalchemy/mysql doesn't contain the charset=utf8 or use_unicode=1 parameters (and the default mysql connection charset is not utf8), sqlalchemy will connect to mysql in ascii mode; In ascii mode, it will attempt to reencode all input data to latin-1 regardless of the database/table collation setting. This catches that error and turns it into an invalid parameter. (The error message associated with this is something like UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2026' in position 30: ordinal not in range(256)) This fixes bug 944034 and is related to bug 898808 Change-Id: I082b7568ef9e9d2104e13aa58d207535ef201bd3 --- nova/api/openstack/wsgi.py | 3 +++ nova/exception.py | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py index 9be0501fdde..02bf0900c64 100644 --- a/nova/api/openstack/wsgi.py +++ b/nova/api/openstack/wsgi.py @@ -574,6 +574,9 @@ def __exit__(self, ex_type, ex_value, ex_traceback): if isinstance(ex_value, exception.NotAuthorized): msg = unicode(ex_value) raise Fault(webob.exc.HTTPForbidden(explanation=msg)) + elif isinstance(ex_value, exception.Invalid): + raise Fault(exception.ConvertedException( + code=ex_value.code, explanation=unicode(ex_value))) elif isinstance(ex_value, TypeError): exc_info = (ex_type, ex_value, ex_traceback) LOG.error(_('Exception handling resource: %s') % ex_value, diff --git a/nova/exception.py b/nova/exception.py index 3caab94658f..43d16642f72 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -88,6 +88,8 @@ def wrap_db_error(f): def _wrap(*args, **kwargs): try: return f(*args, **kwargs) + except UnicodeEncodeError: + raise InvalidUnicodeParameter() except Exception, e: LOG.exception(_('DB exception wrapped.')) raise DBError(e) @@ -275,6 +277,11 @@ class InvalidRPCConnectionReuse(Invalid): message = _("Invalid reuse of an RPC connection.") +class InvalidUnicodeParameter(Invalid): + message = _("Invalid Parameter: " + "Unicode is not supported by the current database.") + + # Cannot be templated as the error syntax varies. # msg needs to be constructed when raised. class InvalidParameterValue(Invalid):