Fix provided instance providers error handing in asynchronous mode

This commit is contained in:
Roman Mogylatov 2021-03-18 19:15:56 -04:00
parent 702df9676c
commit d72580683d
4 changed files with 1323 additions and 964 deletions

View File

@ -13,6 +13,7 @@ Development version
- Improve providers' copying. - Improve providers' copying.
- Improve typing in wiring module. - Improve typing in wiring module.
- Fix wiring module loader uninstallation issue. - Fix wiring module loader uninstallation issue.
- Fix provided instance providers error handing in asynchronous mode.
4.30.0 4.30.0
------ ------

File diff suppressed because it is too large Load Diff

View File

@ -4009,8 +4009,8 @@ cdef class AttributeGetter(Provider):
try: try:
provided = future.result() provided = future.result()
result = getattr(provided, self.name) result = getattr(provided, self.name)
except Exception: except Exception as exception:
pass future_result.set_exception(exception)
else: else:
future_result.set_result(result) future_result.set_result(result)
@ -4088,8 +4088,12 @@ cdef class ItemGetter(Provider):
return provided[self.name] return provided[self.name]
def _async_provide(self, future_result, future): def _async_provide(self, future_result, future):
try:
provided = future.result() provided = future.result()
result = provided[self.name] result = provided[self.name]
except Exception as exception:
future_result.set_exception(exception)
else:
future_result.set_result(result) future_result.set_result(result)
@ -4222,6 +4226,7 @@ cdef class MethodCaller(Provider):
) )
def _async_provide(self, future_result, args, kwargs, future): def _async_provide(self, future_result, args, kwargs, future):
try:
call = future.result() call = future.result()
result = __call( result = __call(
call, call,
@ -4232,6 +4237,9 @@ cdef class MethodCaller(Provider):
self.__kwargs, self.__kwargs,
self.__kwargs_len, self.__kwargs_len,
) )
except Exception as exception:
future_result.set_exception(exception)
else:
future_result.set_result(result) future_result.set_result(result)

View File

@ -655,6 +655,32 @@ class ProvidedInstanceTests(AsyncTestCase):
self.assertIs(instance2.resource, RESOURCE1) self.assertIs(instance2.resource, RESOURCE1)
self.assertIs(instance1.resource, instance2.resource) self.assertIs(instance1.resource, instance2.resource)
def test_provided_attribute_error(self):
async def raise_exception():
raise RuntimeError()
class TestContainer(containers.DeclarativeContainer):
client = providers.Factory(raise_exception)
container = TestContainer()
with self.assertRaises(RuntimeError):
self._run(container.client.provided.attr())
def test_provided_attribute_undefined_attribute(self):
class TestClient:
def __init__(self, resource):
self.resource = resource
class TestContainer(containers.DeclarativeContainer):
resource = providers.Resource(init_resource, providers.Object(RESOURCE1))
client = providers.Factory(TestClient, resource=resource)
container = TestContainer()
with self.assertRaises(AttributeError):
self._run(container.client.provided.attr())
def test_provided_item(self): def test_provided_item(self):
class TestClient: class TestClient:
def __init__(self, resource): def __init__(self, resource):
@ -685,6 +711,28 @@ class ProvidedInstanceTests(AsyncTestCase):
self.assertIs(instance2.resource, RESOURCE1) self.assertIs(instance2.resource, RESOURCE1)
self.assertIs(instance1.resource, instance2.resource) self.assertIs(instance1.resource, instance2.resource)
def test_provided_item_error(self):
async def raise_exception():
raise RuntimeError()
class TestContainer(containers.DeclarativeContainer):
client = providers.Factory(raise_exception)
container = TestContainer()
with self.assertRaises(RuntimeError):
self._run(container.client.provided['item']())
def test_provided_item_undefined_item(self):
class TestContainer(containers.DeclarativeContainer):
resource = providers.Resource(init_resource, providers.Object(RESOURCE1))
client = providers.Factory(dict, resource=resource)
container = TestContainer()
with self.assertRaises(KeyError):
self._run(container.client.provided['item']())
def test_provided_method_call(self): def test_provided_method_call(self):
class TestClient: class TestClient:
def __init__(self, resource): def __init__(self, resource):
@ -715,6 +763,31 @@ class ProvidedInstanceTests(AsyncTestCase):
self.assertIs(instance2.resource, RESOURCE1) self.assertIs(instance2.resource, RESOURCE1)
self.assertIs(instance1.resource, instance2.resource) self.assertIs(instance1.resource, instance2.resource)
def test_provided_method_call_parent_error(self):
async def raise_exception():
raise RuntimeError()
class TestContainer(containers.DeclarativeContainer):
client = providers.Factory(raise_exception)
container = TestContainer()
with self.assertRaises(RuntimeError):
self._run(container.client.provided.method.call()())
def test_provided_method_call_error(self):
class TestClient:
def method(self):
raise RuntimeError()
class TestContainer(containers.DeclarativeContainer):
client = providers.Factory(TestClient)
container = TestContainer()
with self.assertRaises(RuntimeError):
self._run(container.client.provided.method.call()())
class DependencyTests(AsyncTestCase): class DependencyTests(AsyncTestCase):