diff options
| author | Tim Burke <tim.burke@gmail.com> | 2016-04-14 14:18:16 -0700 |
|---|---|---|
| committer | Tim Burke <tim.burke@gmail.com> | 2016-04-14 21:12:35 -0700 |
| commit | 926330d3726e9ce7001190730c69bf6ee45b422a (patch) | |
| tree | 6ece4dd5e0a9f01b31c3b025f7f0d981cee0794e /openstackclient/common/clientmanager.py | |
| parent | ef68f23de3886cac3e92a45537d5eb2136ae150a (diff) | |
| download | python-openstackclient-926330d3726e9ce7001190730c69bf6ee45b422a.tar.gz | |
Propagate AttributeErrors when lazily loading plugins
Previously, if an AttributeError was raised in a plugin's make_client
method, the plugin simply wouldn't be an attribute of the ClientManager,
producing tracebacks like
Traceback (most recent call last):
File ".../openstackclient/shell.py", line 118, in run
ret_val = super(OpenStackShell, self).run(argv)
...
File ".../openstackclient/object/v1/container.py", line 150, in take_action
data = self.app.client_manager.object_store.container_list(
File ".../openstackclient/common/clientmanager.py", line 66, in __getattr__
raise AttributeError(name)
AttributeError: object_store
This made writing minimal third-party auth plugins difficult, as it
obliterated the original AttributeError.
Now, AttributeErrors that are raised during plugin initialization will
be re-raised as PluginAttributeErrors, and the original traceback will
be preserved. This gives much more useful information to plugin
developers, as in
Traceback (most recent call last):
File ".../openstackclient/shell.py", line 118, in run
ret_val = super(OpenStackShell, self).run(argv)
...
File ".../openstackclient/object/v1/container.py", line 150, in take_action
data = self.app.client_manager.object_store.container_list(
File ".../openstackclient/common/clientmanager.py", line 57, in __get__
err_val, err_tb)
File ".../openstackclient/common/clientmanager.py", line 51, in __get__
self._handle = self.factory(instance)
File ".../openstackclient/object/client.py", line 35, in make_client
interface=instance._interface,
File ".../openstackclient/common/clientmanager.py", line 258,
in get_endpoint_for_service_type
endpoint = self.auth_ref.service_catalog.url_for(
PluginAttributeError: 'NoneType' object has no attribute 'url_for'
Change-Id: I0eee7eba6eccc6d471a699a381185c4e76da10bd
Diffstat (limited to 'openstackclient/common/clientmanager.py')
| -rw-r--r-- | openstackclient/common/clientmanager.py | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py index 6d23b55e..8b0fb921 100644 --- a/openstackclient/common/clientmanager.py +++ b/openstackclient/common/clientmanager.py @@ -22,8 +22,10 @@ import sys from oslo_utils import strutils import requests +import six from openstackclient.api import auth +from openstackclient.common import exceptions from openstackclient.common import session as osc_session from openstackclient.identity import client as identity_client @@ -45,7 +47,13 @@ class ClientCache(object): def __get__(self, instance, owner): # Tell the ClientManager to login to keystone if self._handle is None: - self._handle = self.factory(instance) + try: + self._handle = self.factory(instance) + except AttributeError as err: + # Make sure the failure propagates. Otherwise, the plugin just + # quietly isn't there. + new_err = exceptions.PluginAttributeError(err) + six.reraise(new_err.__class__, new_err, sys.exc_info()[2]) return self._handle |
