Browse Source

Brick fix BrickException message formatting

This patch fixes an issue when passing in a
formatting key and value for formatted
text messages for all Brick exceptions.

Added unit tests for brick's exception

Change-Id: I76dcfc6872ca20305d1844162dd0ae28c4bb565c
Related-Bug: 1238085
tags/2014.1.b3
Walter A. Boring IV 5 years ago
parent
commit
f134e3becb
2 changed files with 72 additions and 7 deletions
  1. 10
    7
      cinder/brick/exception.py
  2. 62
    0
      cinder/tests/brick/test_brick_exception.py

+ 10
- 7
cinder/brick/exception.py View File

@@ -14,8 +14,6 @@
14 14
 
15 15
 """Exceptions for the Brick library."""
16 16
 
17
-import sys
18
-
19 17
 from cinder.openstack.common.gettextutils import _
20 18
 from cinder.openstack.common import log as logging
21 19
 
@@ -30,7 +28,7 @@ class BrickException(Exception):
30 28
     a 'msg_fmt' property. That msg_fmt will get printf'd
31 29
     with the keyword arguments provided to the constructor.
32 30
     """
33
-    msg_fmt = _("An unknown exception occurred.")
31
+    message = _("An unknown exception occurred.")
34 32
     code = 500
35 33
     headers = {}
36 34
     safe = False
@@ -46,23 +44,28 @@ class BrickException(Exception):
46 44
 
47 45
         if not message:
48 46
             try:
49
-                message = self.msg_fmt % kwargs
47
+                message = self.message % kwargs
50 48
 
51 49
             except Exception:
52
-                exc_info = sys.exc_info()
53 50
                 # kwargs doesn't match a variable in the message
54 51
                 # log the issue and the kwargs
55 52
                 msg = (_("Exception in string format operation.  msg='%s'")
56
-                       % self.msg_fmt)
53
+                       % self.message)
57 54
                 LOG.exception(msg)
58 55
                 for name, value in kwargs.iteritems():
59 56
                     LOG.error("%s: %s" % (name, value))
60 57
 
61 58
                 # at least get the core message out if something happened
62
-                message = self.msg_fmt
59
+                message = self.message
63 60
 
61
+        # Put the message in 'msg' so that we can access it.  If we have it in
62
+        # message it will be overshadowed by the class' message attribute
63
+        self.msg = message
64 64
         super(BrickException, self).__init__(message)
65 65
 
66
+    def __unicode__(self):
67
+        return unicode(self.msg)
68
+
66 69
 
67 70
 class NotFound(BrickException):
68 71
     message = _("Resource could not be found.")

+ 62
- 0
cinder/tests/brick/test_brick_exception.py View File

@@ -0,0 +1,62 @@
1
+
2
+# Copyright 2010 United States Government as represented by the
3
+# Administrator of the National Aeronautics and Space Administration.
4
+# All Rights Reserved.
5
+#
6
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
7
+#    not use this file except in compliance with the License. You may obtain
8
+#    a copy of the License at
9
+#
10
+#         http://www.apache.org/licenses/LICENSE-2.0
11
+#
12
+#    Unless required by applicable law or agreed to in writing, software
13
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
+#    License for the specific language governing permissions and limitations
16
+#    under the License.
17
+
18
+from cinder.brick import exception
19
+from cinder import test
20
+
21
+
22
+class BrickExceptionTestCase(test.TestCase):
23
+    def test_default_error_msg(self):
24
+        class FakeBrickException(exception.BrickException):
25
+            message = "default message"
26
+
27
+        exc = FakeBrickException()
28
+        self.assertEqual(unicode(exc), 'default message')
29
+
30
+    def test_error_msg(self):
31
+        self.assertEqual(unicode(exception.BrickException('test')), 'test')
32
+
33
+    def test_default_error_msg_with_kwargs(self):
34
+        class FakeBrickException(exception.BrickException):
35
+            message = "default message: %(code)s"
36
+
37
+        exc = FakeBrickException(code=500)
38
+        self.assertEqual(unicode(exc), 'default message: 500')
39
+
40
+    def test_error_msg_exception_with_kwargs(self):
41
+        # NOTE(dprince): disable format errors for this test
42
+        self.flags(fatal_exception_format_errors=False)
43
+
44
+        class FakeBrickException(exception.BrickException):
45
+            message = "default message: %(mispelled_code)s"
46
+
47
+        exc = FakeBrickException(code=500)
48
+        self.assertEqual(unicode(exc), 'default message: %(mispelled_code)s')
49
+
50
+    def test_default_error_code(self):
51
+        class FakeBrickException(exception.BrickException):
52
+            code = 404
53
+
54
+        exc = FakeBrickException()
55
+        self.assertEqual(exc.kwargs['code'], 404)
56
+
57
+    def test_error_code_from_kwarg(self):
58
+        class FakeBrickException(exception.BrickException):
59
+            code = 500
60
+
61
+        exc = FakeBrickException(code=404)
62
+        self.assertEqual(exc.kwargs['code'], 404)

Loading…
Cancel
Save