Debugging¶
You made it to the final chapter. You’re no longer just a user — you’re a practitioner of FunDI!
Testing is good, but debugging is what separates the script kiddie from the software monk
- FunDI provides useful functions to help you debug and optimize your dependency injection:
tree— Generates a tree that shows how dependencies will be resolved — including resolution order and value mapping.from fundi import Scope, tree, scan print(tree(Scope({"username": "user"}), scan(application)))
Outputs:
{'call': <function application at ...>, 'values': {'username': 'user', 'user': {'call': <function require_user at ...>, 'values': {'username': 'user'}}}}
Each node contains the function being called (
call) and the values being injected into it (values).order— generates list that contains order in which dependencies will be called.Note: Result does not include function that is being passed to
orderfunction.from fundi import Scope, order, scan print(order(Scope({"username": "user"}), scan(application)))
Outputs:
[<function require_user at ...>]
Want more details? Try
tree(). Want less pain? Good luck.
Exceptions¶
During injection an exception may be raised, so you should understand why it happens.
Scope value not found¶
If the scope does not contain the value required by a dependency — FunDI will raise ScopeValueNotFoundError
Tracing¶
FunDI helps you understand direct cause of exceptions and place where did they happen — library adds its injection trace to exception.
from contextlib import ExitStack
from fundi import Scope, from_, scan, inject, injection_trace
def require_random_animal() -> str:
raise ConnectionRefusedError("Failed to connect to server :<")
return random.choice(["cat", "dog", "chicken", "horse", "platypus", "cow"])
def application(
animal: str = from_(require_random_animal),
):
print("Animal:", animal)
try:
inject(Scope(), scan(application))
except Exception as e:
print(injection_trace(e))
Output would be:
InjectionTrace(info=CallableInfo(call=<function application at ...>, ...), values={}, origin=InjectionTrace(info=CallableInfo(call=<function require_random_animal at ...>, ...), values={}, origin=None))