Skip to content

Errors

errors

Exceptions raised by depin, all rooted at DepinError.

Every failure depin raises inherits DepinError, so a single except DepinError handles the library uniformly. Errors that a caller might reasonably want to catch as a standard Python exception also inherit the matching builtin — InvalidProviderError is a TypeError, InvalidScopeError is a ValueError, TeardownError is a RuntimeError.

DepinError

Bases: Exception

Base class for every error raised by depin.

Catch this to handle any depin failure uniformly; catch a subclass for a specific cause. No depin code path raises an exception outside this hierarchy.

MissingProviderError

Bases: DepinError

No provider is registered for a requested key.

Raised at Container.freeze() for an unsatisfied dependency, or at resolution time for an unregistered key. Resolve by binding the key on the Container, passing the right tag, or giving the parameter a default.

CircularDependencyError

Bases: DepinError

A cycle was detected in the dependency graph.

Raised by Container.freeze(). Break the cycle by introducing a Token or interface seam, or restructuring so one side no longer depends on the other.

AsyncInSyncContextError

Bases: DepinError

A synchronous operation requires asynchronous execution.

Raised by FrozenContainer.resolve() (or frozen[key]) when the target — or something it depends on — is an async provider. It also guards FrozenContainer.close() when an event loop or async work needs to keep running. Use the matching asynchronous API instead.

ContainerLifecycleError

Bases: DepinError, RuntimeError

A container operation conflicts with active work or shutdown.

ContainerClosedError

Bases: ContainerLifecycleError

A terminally closed container cannot resolve values or open scopes.

OutsideScopeError

Bases: DepinError

A scoped binding was resolved with no active scope.

Raised when a Scope.SCOPED provider is resolved outside any FrozenContainer.scope() / ascope block. Open a scope around the resolution, or make the provider a singleton.

DuplicateProviderError

Bases: DepinError

Two bindings resolve to the same key and tag.

Raised by Container.freeze(). Remove the redundant binding, or give the implementations distinct tag values to register several under one key.

CaptiveDependencyError

Bases: DepinError

A singleton depends on a scoped provider it would capture for life.

Raised by Container.freeze(). A singleton outlives every scope, so it would pin one scope's instance forever. Make the consumer scoped, or the dependency a singleton.

InvalidProviderError

Bases: DepinError, TypeError

A binding does not carry the type information depin needs.

Raised while declaring a provider or constructing a Catalog / Manifest when its target, metadata, ownership, or members are invalid. It also reports malformed Bindings sources and records() results before collector state changes. At Container.freeze(), it identifies missing type information, invalid keys, and unsupported provider shapes; at resolution time, it reports a value incompatible with its declared shape.

Inherits TypeError, so existing except TypeError handlers keep working.

Example
>>> from depin import provider
>>> from depin.errors import InvalidProviderError
>>> try:
...     provider(42)
... except InvalidProviderError as error:
...     str(error).startswith('cannot declare')
True

InvalidScopeError

Bases: DepinError, ValueError

A binding requests a lifetime it cannot have.

Raised by Container.freeze() when a generator or context-manager provider is bound as Scope.TRANSIENT: such providers own a teardown, and a transient value is never cached, so nothing would ever drain it. Bind it as singleton or scoped.

Inherits ValueError, so existing except ValueError handlers keep working.

TeardownError

Bases: DepinError, RuntimeError

A provider's teardown could not run correctly.

Raised when a generator provider yields a second time during teardown (a provider must yield exactly once), or when an async teardown is drained from a synchronous scope. Individual teardown failures raised by user code are collected into an ExceptionGroup instead, so one failure never hides another.

Inherits RuntimeError, so existing except RuntimeError handlers keep working.

ContainerNotBoundError

Bases: DepinError, RuntimeError

No container is hosted in the context a dependency was resolved from.

Raised by depin.hosted_container() when no depin.Host has published a container here, and by an integration that reads the host itself — the FastAPI integration raises it when Inject[T] is evaluated outside a RequestScope, naming the middleware to install.

Resolve it by opening a scope with Host.scope() / Host.ascope() around the unit of work, or by publishing the container with Host.activated().

Inherits RuntimeError, so existing except RuntimeError handlers keep working.

FastAPIIntegrationError

Bases: DepinError, RuntimeError

FastAPI installation could not compile routes safely.

Raised by depin.ext.fastapi.install() when the application was started, was already installed with another container, or exposes an unsupported route shape. Upgrade FastAPI to a tested release or use the compatible RequestScope middleware instead.

Inherits RuntimeError, so existing except RuntimeError handlers keep working.