[Kimchi-devel] [PATCH] kimchi.exception: Properly Decode All Kinds of Exception Arguments
Zhou Zheng Sheng
zhshzhou at linux.vnet.ibm.com
Wed Apr 2 05:46:35 UTC 2014
Hi Aline,
This patch fix the bug triggered by "AsyncTask: Propagate cherrypy
request information to worker threads".
on 2014/04/02 13:42, 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!
Zhou Zheng Sheng / 周征晟
E-mail: zhshzhou at linux.vnet.ibm.com
Telephone: 86-10-82454397
More information about the Kimchi-devel
mailing list