model proxy: Throw custom exception when model not cached

Currently, when attempting to access fields on a model which is not
cached, the esception thrown complains that NoneType doesn't have the
attribute. This message does not say much.

This change makes the exception include the proxy object which failed
cache-lookup. It also adds a log message stating the lookup failed.

Change-Id: I6e77eeefa44307f92b7c40be7349a07ce5b67407
This commit is contained in:
Omer Anson 2017-08-21 16:55:29 +03:00
parent 939f878cda
commit 8186236bce
3 changed files with 24 additions and 2 deletions

View File

@ -52,6 +52,10 @@ class DBKeyNotFound(DragonflowException):
message = _('DB Key not found, key=%(key)s')
class ReferencedObjectNotFound(DragonflowException):
message = _('Referenced object not found. proxy=%(proxy)s')
class CommandError(DragonflowException):
message = _("Non-existent fields are specified: %(non_existent_fields)s")

View File

@ -12,10 +12,16 @@
import copy
import six
from oslo_log import log
from dragonflow._i18n import _
from dragonflow.common import exceptions
from dragonflow.db import db_store
LOG = log.getLogger(__name__)
class _ModelProxyBase(object):
'''Base for proxy objects
@ -74,8 +80,12 @@ class _ModelProxyBase(object):
return not self == other
def __getattr__(self, name):
if name != '_obj':
return getattr(self.get_object(), name)
if name == '_obj':
return
obj = self.get_object()
if obj is None:
raise exceptions.ReferencedObjectNotFound(proxy=self)
return getattr(obj, name)
def __copy__(self):
return self.__class__(self._id)

View File

@ -10,10 +10,12 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
import testtools
from jsonmodels import fields
import mock
from dragonflow.common import exceptions
from dragonflow.db import db_store
import dragonflow.db.field_types as df_fields
import dragonflow.db.model_framework as mf
@ -179,3 +181,9 @@ class TestObjectProxy(tests_base.BaseTestCase):
self.assertEqual(model_test_ref, model_test_ref_deepcopy)
self.assertNotEqual(id(model_test_ref), id(model_test_ref_copy))
self.assertNotEqual(id(model_test_ref), id(model_test_ref_deepcopy))
def test_non_existing_reference(self):
reffing_model = RefferingModel(id='2', model_test='1')
self.db_store.get_one.return_value = None
with testtools.ExpectedException(exceptions.ReferencedObjectNotFound):
topic = reffing_model.model_test.topic # noqa