From 2f3f2664cadada4d85af3a7a11f62a7d5e553aaa Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Oct 11 2012 20:33:04 +0000 Subject: Add instructions support to PublicError When long additional text should follow the error message, one can supply instructions parameter to a class derived from PublicError. This will cause following text added to the error message: Additional instructions: `instructions' optional parameter could be a list or anything that coerces into unicode(). List entries will be joined with '\n'. https://fedorahosted.org/freeipa/ticket/3167 --- diff --git a/ipalib/errors.py b/ipalib/errors.py index 7f11132..a6c8e76 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -265,17 +265,20 @@ class PublicError(StandardError): ) self.format = format self.forwarded = False - def convert_keyword(value): - if isinstance(value, list): - result=u'\n'.join(map(lambda line: unicode(line), value)) - return result - return value - kwargs = dict(map(lambda (k,v): (k, convert_keyword(v)), kw.items())) - self.msg = self.format % kwargs + self.msg = self.format % kw if isinstance(self.format, basestring): - self.strerror = ugettext(self.format) % kwargs + self.strerror = ugettext(self.format) % kw else: - self.strerror = self.format % kwargs + self.strerror = self.format % kw + if 'instructions' in kw: + def convert_instructions(value): + if isinstance(value, list): + result=u'\n'.join(map(lambda line: unicode(line), value)) + return result + return value + instructions = u'\n'.join((unicode(_('Additional instructions:')), + convert_instructions(kw['instructions']))) + self.strerror = u'\n'.join((self.strerror, instructions)) else: if isinstance(message, (Gettext, NGettext)): message = unicode(message) diff --git a/tests/test_ipalib/test_errors.py b/tests/test_ipalib/test_errors.py index 2fcdc56..1421e78 100644 --- a/tests/test_ipalib/test_errors.py +++ b/tests/test_ipalib/test_errors.py @@ -318,6 +318,23 @@ class test_PublicError(PublicExceptionTester): assert inst.text is kw['text'] assert inst.number is kw['number'] + # Test with instructions: + # first build up "instructions", then get error and search for + # lines of instructions appended to the end of the strerror + # despite the parameter 'instructions' not existing in the format + instructions = u"The quick brown fox jumps over the lazy dog".split() + # this expression checks if each word of instructions + # exists in a string as a separate line, with right order + regexp = re.compile('(?ims).*' + + ''.join(map(lambda x: '(%s).*' % (x), + instructions)) + + '$') + inst = subclass(instructions=instructions, **kw) + assert inst.format is subclass.format + assert_equal(inst.instructions, instructions) + inst_match = regexp.match(inst.strerror).groups() + assert_equal(list(inst_match),list(instructions)) + def test_public_errors(): """