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

Zhou Zheng Sheng zhshzhou at linux.vnet.ibm.com
Thu Apr 3 04:07:44 UTC 2014


on 2014/04/03 00:01, Aline Manera wrote:
> 
> Regarding the root cause, I don't think we should display an error
> message with 2 exception
> 
> KCHDR0005E: Unable to generate debug report my-debugreport. Details:
> KCHDR0003E: Unable to create debug report my-debugreport. Details: -9.
> 
> It is odd.
> 
> We should only raise one exception with all the details.

Agree. I updated it in the v2 patch. I'd also like to keep the decoding
improvements for the KimchiException, because it makes KimchiException
accepts not only strings and unicode strings, but also objects that
formats themselves to strings or unicode strings, which is a common and
convenient pattern in exception handling.

> 
> On 04/02/2014 02:42 AM, 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