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 typing in wiring module.
- Fix wiring module loader uninstallation issue.
- Fix provided instance providers error handing in asynchronous mode.
4.30.0
------

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -655,6 +655,32 @@ class ProvidedInstanceTests(AsyncTestCase):
self.assertIs(instance2.resource, RESOURCE1)
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):
class TestClient:
def __init__(self, resource):
@ -685,6 +711,28 @@ class ProvidedInstanceTests(AsyncTestCase):
self.assertIs(instance2.resource, RESOURCE1)
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):
class TestClient:
def __init__(self, resource):
@ -715,6 +763,31 @@ class ProvidedInstanceTests(AsyncTestCase):
self.assertIs(instance2.resource, RESOURCE1)
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):