Errors and exceptions¶
Every exception modern-di raises lives in modern_di.exceptions and descends from a single
root, ModernDIError. The hierarchy is grouped by when the failure happens — registering
providers, validating the graph, resolving a type, or closing a container — so you can catch a
whole category with one except.
Hierarchy¶
ModernDIError (RuntimeError)
├── ContainerError
│ ├── InvalidChildScopeError
│ ├── MaxScopeReachedError
│ ├── ScopeNotInitializedError
│ ├── ScopeSkippedError
│ ├── InvalidScopeTypeError
│ ├── ContainerClosedError
│ └── ValidationFailedError
├── ResolutionError
│ ├── ProviderNotRegisteredError
│ ├── AliasSourceNotRegisteredError
│ ├── ArgumentResolutionError
│ ├── CircularDependencyError
│ └── CreatorCallError
├── RegistrationError
│ ├── DuplicateProviderTypeError
│ ├── UnknownFactoryKwargError
│ ├── UnsupportedCreatorParameterError
│ └── InvalidScopeDependencyError
├── FinalizerError
├── AsyncFinalizerInSyncCloseError
└── GroupInstantiationError
Root¶
ModernDIError— base class for every error the library raises. It subclassesRuntimeErrorfor backwards compatibility, soexcept RuntimeErrorkeeps working. CatchModernDIErrorto handle any framework error in one place.
ContainerError — container and scope problems¶
Catch ContainerError for any container/scope failure.
InvalidChildScopeError— raised whenbuild_child_container(scope=...)is given a scope that is not deeper than the parent's (or the constructor receives a parent at an equal/shallower scope). The error lists the scopes that are allowed.MaxScopeReachedError— raised bybuild_child_container()with no explicitscopewhen the parent is already at the deepest scope (STEP), so there is no next level to advance to.ScopeNotInitializedError— raised during resolution when a provider needs a scope deeper than the current container's, and no container at that scope exists in the chain (e.g. resolving aREQUEST-scoped provider from theAPPcontainer). See Troubleshooting: Scope chain.ScopeSkippedError— raised during resolution when the target scope is shallower than the current container but is missing from the scope chain (a level was skipped when building children). See Troubleshooting: Scope chain.InvalidScopeTypeError— raised by theContainerconstructor whenscopeis not anenum.IntEnum.ContainerClosedError— raised when you resolve from, or build a child of, a container that has been closed (close_sync()/close_async()ran, or awithblock exited). Re-enter thewithblock to reopen it.ValidationFailedError— raised byContainer.validate()(andContainer(..., validate=True)) when the graph has problems. Catch this for validation results; its.errorsattribute holds the list of individual issues (each itself aResolutionErrororRegistrationError), andstr()renders them all.
ResolutionError — failures while resolving a type¶
Catch ResolutionError for any resolution failure. These carry a dependency_path that is
accumulated as the error propagates, so the message shows the full chain from the requested type
down to the failing dependency. dependency_path is a list[ResolutionStep], where each
ResolutionStep (importable from modern_di.exceptions) has a .scope and a .name — inspect it
to render the chain programmatically.
ProviderNotRegisteredError— raised byresolve(SomeType)when no provider is registered for the type. The message includes "did you mean…" suggestions when a close match exists. See Troubleshooting: Missing provider.AliasSourceNotRegisteredError— raised when anAliaspoints at asource_typethat has no registered provider (eagerly duringvalidate(), or at resolution time).ArgumentResolutionError— raised when a creator parameter cannot be resolved: no provider matches its annotated type, or the parameter is unannotated. See Troubleshooting: Context not set.CircularDependencyError— raised when the provider graph contains a cycle (A → B → A), detected duringvalidate()or at resolution; the message shows the cycle path. See Troubleshooting: Circular dependency.CreatorCallError— raised when a creator's dependencies all resolved but the creator itself raised while being called. The original exception is preserved on.original_error(and as the__cause__).
RegistrationError — declaration / registration problems¶
Catch RegistrationError for declaration- and registration-time problems.
DuplicateProviderTypeError— raised when two providers are registered for the same bound type (within one group, across groups passed together, or against an already-registered type). See Troubleshooting: Duplicate type.UnknownFactoryKwargError— raised whenFactory(kwargs={...})contains a key that is not a parameter of the creator's signature; lists the known parameters and "did you mean" hints.UnsupportedCreatorParameterError— raised when a creator's signature has a parametermodern-dicannot wire (e.g. an unsupported kind); names the parameter and the reason.InvalidScopeDependencyError— raised when a provider depends on another provider bound to a deeper scope than its own (a longer-lived provider depending on a shorter-lived one). Surfaced byvalidate().
Direct ModernDIError subclasses¶
These don't fit the register/resolve/validate grouping:
FinalizerError— raised byclose_sync()/close_async()when one or more finalizers raised during cleanup. The remaining finalizers still run; all errors are aggregated into this single exception..finalizer_errorsholds the list and.is_asyncrecords which close path ran. See Lifecycle.AsyncFinalizerInSyncCloseError— raised whenclose_sync()reaches a cached resource whose finalizer is async. Becauseclose_sync()aggregates, this arrives wrapped inside aFinalizerError(as an entry in.finalizer_errors), not on its own. The cache is retained so a laterawait close_async()can finalize it. See Lifecycle.GroupInstantiationError— raised when aGroupsubclass is instantiated. Groups are namespaces and must never be created as objects.
Security note¶
modern-di exception messages are intended for developers (logs, tracebacks during wiring). A
CreatorCallError embeds the wrapped exception's text, and a FinalizerError embeds the repr of every
finalizer exception — so if a creator or finalizer raises an error whose message contains sensitive
runtime data, that text becomes part of the modern-di message. The DI-specific errors themselves are
conservative (type names and provider reprs only; context values are keyed by type and never repr'd).
Applications must not echo raw exception strings to untrusted clients.