Skip to content

Commit e3a6fc2

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Propagate AttributeErrors when lazily loading plugins"
2 parents 8944585 + 926330d commit e3a6fc2

3 files changed

Lines changed: 24 additions & 1 deletion

File tree

openstackclient/common/clientmanager.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222

2323
from oslo_utils import strutils
2424
import requests
25+
import six
2526

2627
from openstackclient.api import auth
28+
from openstackclient.common import exceptions
2729
from openstackclient.common import session as osc_session
2830
from openstackclient.identity import client as identity_client
2931

@@ -45,7 +47,13 @@ def __init__(self, factory):
4547
def __get__(self, instance, owner):
4648
# Tell the ClientManager to login to keystone
4749
if self._handle is None:
48-
self._handle = self.factory(instance)
50+
try:
51+
self._handle = self.factory(instance)
52+
except AttributeError as err:
53+
# Make sure the failure propagates. Otherwise, the plugin just
54+
# quietly isn't there.
55+
new_err = exceptions.PluginAttributeError(err)
56+
six.reraise(new_err.__class__, new_err, sys.exc_info()[2])
4957
return self._handle
5058

5159

openstackclient/common/exceptions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ class AuthorizationFailure(Exception):
2424
pass
2525

2626

27+
class PluginAttributeError(Exception):
28+
"""A plugin threw an AttributeError while being lazily loaded."""
29+
# This *must not* inherit from AttributeError;
30+
# that would defeat the whole purpose.
31+
pass
32+
33+
2734
class NoTokenLookupException(Exception):
2835
"""This does not support looking up endpoints from an existing token."""
2936
pass

openstackclient/tests/common/test_clientmanager.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
class Container(object):
4343
attr = clientmanager.ClientCache(lambda x: object())
44+
buggy_attr = clientmanager.ClientCache(lambda x: x.foo)
4445

4546
def __init__(self):
4647
pass
@@ -72,6 +73,13 @@ def test_singleton(self):
7273
c = Container()
7374
self.assertEqual(c.attr, c.attr)
7475

76+
def test_attribute_error_propagates(self):
77+
c = Container()
78+
err = self.assertRaises(exc.PluginAttributeError,
79+
getattr, c, 'buggy_attr')
80+
self.assertNotIsInstance(err, AttributeError)
81+
self.assertEqual("'Container' object has no attribute 'foo'", str(err))
82+
7583

7684
class TestClientManager(utils.TestCase):
7785

0 commit comments

Comments
 (0)