Exceptions & Status Codes¶
The exception hierarchy, the built-in handlers, and the status-code constants.
Every exception below inherits VeloceError, so except VeloceError catches
anything the framework raised regardless of which family it came from.
VeloceError
¶
Bases: Exception
Root of every exception Veloce raises.
Mixed into each exception family the framework defines - HTTP errors,
validation failures, WebSocket closes, routing and setup errors, JWT and
signature failures - so except VeloceError answers "did this come from
Veloce?" in one clause. Families that already subclassed a stdlib type
keep it: DuplicateRouteError is still a ValueError and
FilesKeyError is still a KeyError, so every handler that matched
before still matches. VeloceError is listed first in those bases, so a
handler registered against it wins the MRO walk over a broader stdlib
handler.
HTTPException
¶
Bases: VeloceError
HTTP error with status code and detail.
Either subclass with a fixed code (and optional description),
or instantiate HTTPException(status_code, detail, headers) directly.
ValidationError
¶
Bases: UnprocessableEntity
Request validation error (422).
Subclasses UnprocessableEntity so handlers registered against either
UnprocessableEntity or HTTPException catch it via the MRO walk
Veloce performs in error dispatch.
RequestValidationError
¶
Bases: ValidationError
Framework-level request validation failure (422).
Raised by the dependency resolver when path / query / header / cookie /
body / form / file parameters fail validation. Distinct from a
user-level ValidationError so handlers can pick one or the other:
@app.exception_handler(RequestValidationError)
async def on_req_invalid(request, exc):
return JSONResponse(
{"errors": exc.errors},
status_code=HTTP_422_UNPROCESSABLE_ENTITY,
)
Subclasses ValidationError so existing except ValidationError
handlers continue to catch it via the MRO walk.
WebSocketException
¶
Bases: VeloceError
Raised inside a WebSocket handler to close the connection cleanly.
ASGI shape. The dispatch layer catches it and sends a
close frame carrying code (RFC 6455 Sec. 7.4.1) and the optional
reason - no traceback is propagated, since this is an
application-driven close rather than an internal error.
WebSocketDisconnect
¶
WebSocketRequestValidationError
¶
Bases: RequestValidationError
A WebSocket dependency failed parameter validation.
Raised when a Depends() resolved during a
WebSocket handshake reports a RequestValidationError. The
dispatch layer closes the connection with code 1008 (policy
violation) rather than 1011 (internal error), since the failure is
a client-side contract violation, not a server fault.
BuildError
¶
Bases: VeloceError, LookupError
url_for could not build a URL for the given endpoint.
Carries the endpoint name and the values that were being substituted
so registered app.url_build_error_handlers callbacks can recover
(e.g. fall back to a different endpoint, or fetch from an external
routing table) by inspecting the failure and returning a URL string.
ConfigurationError
¶
Bases: VeloceError, RuntimeError
A handler or route was declared in a way that cannot be resolved.
Raised at registration time, never per request, so a genuinely ambiguous parameter declaration becomes a startup error instead of a silent mis-binding discovered only at runtime. Carries the offending parameter name so the message points straight at the conflict.
DuplicateRouteError
¶
Bases: VeloceError, ValueError
Two handlers were registered for the same path and HTTP method.
Raised at registration time when a route would silently overwrite an
existing handler. Carries the conflicting path, method, and both handler
qualified names so the message points at the exact collision. Configure
the policy per router with on_duplicate="error"|"warn"|"override".
FilesKeyError
¶
Bases: VeloceError, KeyError
Descriptive miss on request.files raised in debug mode.
Subclasses KeyError so handlers that already catch the bare lookup
miss keep working, while the message explains the most common cause:
the field was submitted as a plain form value (missing
enctype="multipart/form-data") or the body was JSON rather than a
multipart upload. Only raised when app.debug is set; production
keeps the plain KeyError semantics.
SetupError
¶
Bases: VeloceError, RuntimeError
A registration ran after the application started serving.
Routes, hooks, blueprints, middleware, and similar setup must be wired
before the first request is dispatched. Once serving begins the route
table and hook lists are frozen, so a late mutation - which would race
in-flight requests under concurrent ASGI dispatch - raises this instead
of silently corrupting the live application. The lock is relaxed in
DEBUG/TESTING so hot-reload and test monkeypatching stay ergonomic.
http_exception_handler
async
¶
http_exception_handler(request: Any, exc: HTTPException) -> Response
Render an HTTPException as a JSON {"detail": ..., "status_code": ...} response.
Honours exc.status_code, exc.detail (falling back to the
subclass description), and exc.headers.
request_validation_exception_handler
async
¶
request_validation_exception_handler(request: Any, exc: RequestValidationError) -> Response
Render a RequestValidationError as a 422 with the error list.
Uses the structured shape {"detail": [ ...per-field errors... ]}.
status
¶
HTTP status codes — convenient named constants.
Usage::
from veloce import status
@app.post("/items", status_code=status.HTTP_201_CREATED)
async def create_item(item: Item):
return item
status_permits_body
¶
Whether a response with this status may carry a payload body.
False for 1xx interim responses (RFC 9110 Sec. 15.2), 204 No Content
(Sec. 15.3.5), 205 Reset Content (Sec. 15.3.6), and 304 Not Modified
(Sec. 15.4.5); True otherwise. None (unknown) allows a body.
Named HTTP errors¶
One class per standard status code. Each carries a fixed code and
description, so raise NotFound("no such item") produces a 404 whose body
defaults to "Not Found". abort(404) raises the same class, which is why a
handler registered against NotFound matches an abort() too.
ServerNotImplemented is the 501 class: NotImplemented is a Python builtin,
so the obvious name is unavailable.
BadRequest
¶
Bases: HTTPException
Unauthorized
¶
Bases: HTTPException
PaymentRequired
¶
Bases: HTTPException
Forbidden
¶
Bases: HTTPException
NotFound
¶
Bases: HTTPException
MethodNotAllowed
¶
Bases: HTTPException
NotAcceptable
¶
Bases: HTTPException
ProxyAuthenticationRequired
¶
Bases: HTTPException
RequestTimeout
¶
Bases: HTTPException
Conflict
¶
Bases: HTTPException
Gone
¶
Bases: HTTPException
LengthRequired
¶
Bases: HTTPException
PreconditionFailed
¶
Bases: HTTPException
RequestEntityTooLarge
¶
Bases: HTTPException
RequestURITooLong
¶
Bases: HTTPException
UnsupportedMediaType
¶
Bases: HTTPException
RangeNotSatisfiable
¶
Bases: HTTPException
ExpectationFailed
¶
Bases: HTTPException
ImATeapot
¶
Bases: HTTPException
UnprocessableEntity
¶
Bases: HTTPException
TooManyRequests
¶
Bases: HTTPException
InternalServerError
¶
Bases: HTTPException
ServerNotImplemented
¶
Bases: HTTPException
BadGateway
¶
Bases: HTTPException
ServiceUnavailable
¶
Bases: HTTPException
GatewayTimeout
¶
Bases: HTTPException