Errors
Error rules, built-in domain errors and the package's exceptions.
See the Errors guide.
ErrorMap.map()
def map(exception: type[E], status: int, *, code: str | None = None, body: Callable[[E], Mapping[str, JSONValue]] | None = None) -> ErrorMap: ...
A new map where exception (and subclasses) produce status.
| Parameter |
Type |
Default |
Description |
exception |
type[E] |
— |
Exception class; subclasses match too. |
status |
int |
— |
HTTP status of the response. |
code |
str \| None |
None |
Machine-readable code (default: the class name in snake_case). |
body |
Callable[[E], Mapping[str, JSONValue]] \| None |
None |
Builds the body from the exception (default {detail, code} or error_body()). |
def mask_validation_input(errors: Iterable[Mapping[str, JSONValue]], schema: type[object] | None = None) -> list[dict[str, JSONValue]]: ...
Mask Sensitive field values a validation error body would otherwise echo back.
| Parameter |
Type |
Default |
Description |
errors |
Iterable[Mapping[str, JSONValue]] |
— |
Error items shaped like pydantic's/Ninja's (a loc, optionally an input). |
schema |
type[object] \| None |
None |
The schema errors were raised against; without one nothing is masked. |
DomainError()
def DomainError(message: str = '', **details: JSON) -> None: ...
Base class for business errors: 400 unless a subclass says otherwise.
| Parameter |
Type |
Default |
Description |
message |
str |
'' |
The detail (default: default_message, else the docstring). |
**details |
JSON |
— |
Extra JSON fields merged into the body. |
Built-in domain errors
| Exception |
Status |
code |
Default detail |
Import |
DomainError |
400 |
domain_error |
Base class for business errors: 400 unless a subclass says otherwise. |
ninja_devx.layers |
PermissionDenied |
403 |
permission_denied |
You do not have permission to perform this action. |
ninja_devx.layers |
PolicyDenied |
403 |
policy_denied |
You do not have permission to perform this action. |
ninja_devx.layers.policies |
MissingTenant |
403 |
tenant_required |
No tenant is associated with this request. |
ninja_devx.security.tenancy |
NotFound |
404 |
not_found |
Not found. |
ninja_devx.layers |
Conflict |
409 |
conflict |
The request conflicts with the current state. |
ninja_devx.layers |
PreconditionFailed |
412 |
precondition_failed |
The resource changed since you last fetched it. |
ninja_devx.http.conditional |
ValidationFailed |
422 |
validation_failed |
Validation failed. |
ninja_devx.layers |
PreconditionRequired |
428 |
precondition_required |
Send If-Match with the ETag you last received. |
ninja_devx.http.conditional |
Exceptions and warnings
| Class |
Base |
When |
NinjaDevXError |
Exception |
Base class for all ninja-devx errors. |
ControllerConfigError |
NinjaDevXError |
A controller or one of its operations is declared incorrectly. |
DependencyResolutionError |
NinjaDevXError |
A dependency could not be resolved by the container. |
CircularDependencyError |
DependencyResolutionError |
The dependency graph contains a cycle. |
AsyncLazyAccessError |
NinjaDevXError |
Sync-only Django code (usually a lazy relation) ran inside an async operation. |
BlockingCallWarning |
RuntimeWarning |
Sync code blocked an async operation's event loop (see NINJA_DEVX["WARN_BLOCKING_MS"]). |
AsyncDatabaseTestWarning |
UserWarning |
An async test uses the database without django_db(transaction=True). |
MixedPathWarning |
UserWarning |
One path is served by both sync and async operations (costs a thread hop per call). |
NinjaDevXDeprecationWarning |
DeprecationWarning |
A ninja-devx API scheduled for removal; the message names the replacement. |