python-dependency-injector icon indicating copy to clipboard operation
python-dependency-injector copied to clipboard

How to fail application if dependency cannot be wired?

Open gtors opened this issue 2 years ago • 4 comments

For example, developer make typo in Provide[...]:

container.py

class ApplicationContainer(containers.DeclarativeContainer):
    some_service = providers.Singleton(object)

app.py

# FastAPI

@app.get("/")
@inject
async def some_handler(service = Depends(Provide["sOme_service"])):  # suppose there is a typo in the name of the container attribute
    # `service` will be <dependency_injector.wiring.Provide object at 0x7f59daf8c580>
    pass

I've tried this approach, but it doesn't work for the Singleton:

Provide["some_service", required()]  # AttributeError: 'dependency_injector.providers.Singleton' object has no attribute 'required'

So, how to crash app in case if dependency cannot be resolved?

gtors avatar Dec 14 '21 20:12 gtors

Why not raise an exception here?

https://github.com/ets-labs/python-dependency-injector/blob/541131e33858ee1b8b5a7590d2bb9f929740ea1e/src/dependency_injector/wiring.py#L546-L547

gtors avatar Dec 14 '21 21:12 gtors

+1 It would be great to have an option to raise an exception when failing to resolve a dependency.

tarohi24 avatar Dec 31 '21 23:12 tarohi24

Does this work for modules not mentioned in wire function? Mb implement into inject decorator?

JanPalasek avatar Jan 30 '22 19:01 JanPalasek

I'm getting started with python-dependency-injector and have been tripped up by some self-imposed wiring errors. The end result is that my methods get called with Provide object when I would prefer an Exception explaining the issue.

My issues have fallen into two buckets:

  1. Improper string identifiers passed into Provide. I have a fix for this which replaces

https://github.com/ets-labs/python-dependency-injector/blob/3858cef657cabaca3dff60890f1a1bea2ea84c97/src/dependency_injector/wiring.py#L235

resolved = self._resolve_string_id(provider, modifier)

if resolved is None:
    raise KeyError(f"Unable to resolve a Provider for '{provider}'")

return resolved
  1. The other errors appear when a Container has not been wired for the Provider. This could be that no containers have been wired or that the wrong type has been wired. I believe the solution is to update _get_sync_patched so it compares patched.reference_[injections|closing] with patched.[injections|closing] to detect missing values. The Modifier could be overloaded to handle these cases so the functionality is opt-in and doesn't change the interface. If that is not desired, another parameter could be added to _Marker which indicates the desired behavior.

I can submit a PR for the first case, and take a look at implementing the second. But I wanted to get some input on the approach before beginning. I realize these issues are bugs in my application and not the library, but these changes would make debugging the issues easier.

jeffmace avatar Sep 02 '22 14:09 jeffmace