[Kimchi-devel] [PATCH] kimchi.exception: Properly Decode All Kinds of Exception Arguments

Sheldon shaohef at linux.vnet.ibm.com
Wed Apr 2 07:09:08 UTC 2014


Reviewed-by: ShaoHe Feng <shaohef at linux.vnet.ibm.com>

This patch will solve these two case.

In [23]: unicode(str(iss), "utf-8")
Out[23]: u'\u4f60\u597d'

In [24]: class ou(object):
def __str__(self):
return u"你好"
....:

In [25]: iu = ou()

In [26]: unicode(iu)
Out[26]: u'\u4f60\u597d'

In [27]: class os(object):
def __str__(self):
return "你好"
....:

In [28]: istr = os()

In [29]: unicode(str(istr), "utf-8")
Out[29]: u'\u4f60\u597d'


On 04/02/2014 01:42 PM, zhshzhou at linux.vnet.ibm.com wrote:
> From: Zhou Zheng Sheng <zhshzhou at linux.vnet.ibm.com>
>
> KimchiException provides the ability to translate each argument and the
> error message. It decodes the translated message to unicode. It's also
> smart and avoids decoding a unicode argument twice by a check to make
> sure the to-be-decoded value is not unicode.
>
> The problem is that when a KimchiException is initialized by another
> KimchiException, for example,
>
> try:
>      ...
> except OperationFailed as e:
>      ...
>      raise OperationFailed('KCHXXXX', {'err': e})
>
> the variable "e" is not a unicode object so it passes the check
> mentioned above, then it gets decoded twice and raises an encoding
> exception.
>
> This patch does not only rely on the type of the to-be-decoded object,
> but also catches the encoding exeption. It firstly try to call str(obj)
> to get the ascii string of the obj, then decodes it to unicode. This is
> valid for a normal string or any object can format itself to a normal
> string. If it fails, it try to call unicode(obj) to get the unicode
> string of the object. This is valid for objects can format themselves
> to a unicode string. In all, it handles various objects like following.
>
> If obj is a unicode string, use it directly.
> If obj is a normal string, decode it to a unicode string.
> If obj can format itself to a normal string, format it and decode it to
> unicode.
> If obj can format itself to a unicode string, format it.
>
> Another problem is that by the current design, KimchiException always
> stores error message in unicode. This can cause encoding exception when
> we call "str(KimchiExceptionObject)". This patch is not a total refactor
> of the translation and encoding so it does not solve this problem. The
> workaround is using KimchiExceptionObject.message instead of str it.
>
> Notice: I'm following the Python str.encode and decode semantics in the
> commit message.
> "encode" means converting unicode sting to ascii/utf-8.
> "decode" means converting ascii/utf-8 string to unicode.
> "encoding" means the action of decode and encode in general.
>
> Signed-off-by: Zhou Zheng Sheng <zhshzhou at linux.vnet.ibm.com>
> ---
>   src/kimchi/asynctask.py | 2 +-
>   src/kimchi/exception.py | 8 +++++++-
>   2 files changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/src/kimchi/asynctask.py b/src/kimchi/asynctask.py
> index 8f0d96c..54fb749 100644
> --- a/src/kimchi/asynctask.py
> +++ b/src/kimchi/asynctask.py
> @@ -68,4 +68,4 @@ class AsyncTask(object):
>           except Exception, e:
>               cherrypy.log.error_log.error("Error in async_task %s " % self.id)
>               cherrypy.log.error_log.error(traceback.format_exc())
> -            cb("Unexpected exception: %s" % str(e), False)
> +            cb("Unexpected exception: %s" % e.message, False)
> diff --git a/src/kimchi/exception.py b/src/kimchi/exception.py
> index 87982ea..fcf60cc 100644
> --- a/src/kimchi/exception.py
> +++ b/src/kimchi/exception.py
> @@ -54,7 +54,13 @@ class KimchiException(Exception):
>
>           for key, value in args.iteritems():
>               if not isinstance(value, unicode):
> -                args[key] = unicode(str(value), 'utf-8')
> +                try:
> +                    # In case the value formats itself to an ascii string.
> +                    args[key] = unicode(str(value), 'utf-8')
> +                except UnicodeEncodeError:
> +                    # In case the value is a KimchiException or it formats
> +                    # itself to a unicode string.
> +                    args[key] = unicode(value)
>
>           return unicode(translation.gettext(text), 'utf-8') % args
>


-- 
Thanks and best regards!

Sheldon Feng(冯少合)<shaohef at linux.vnet.ibm.com>
IBM Linux Technology Center




More information about the Kimchi-devel mailing list