abort()
¶
This will immediately stop the request execution.
The abort()
shortcut in Ravyn lets you immediately stop request processing and raise an HTTP error response—exactly
like Flask's abort()
, but async-native and fully integrated into Ravyn's exception system.
It provides a concise, expressive way to signal HTTP errors from any handler, without manually raising or returning response objects.
Quick Overview¶
from ravyn import get
from ravyn.contrib.responses.shortcuts import abort
@get()
async def endpoint() -> None:
abort(404) # immediately stop execution
When called, abort()
raises an internal HTTPException
that's automatically caught by Ravyn's ExceptionMiddleware
.
Depending on what arguments you pass, it can:
- Return a default status phrase (like
"Not Found"
) - Include a custom message or structured JSON body
- Add custom HTTP headers
- Produce any custom
Response
type (e.g.JSONResponse
,HTMLResponse
, etc.)
Function Signature¶
def abort(
status_code: int,
detail: Any | None = None,
headers: dict[str, Any] | None = None,
) -> None:
...
Parameter | Type | Description |
---|---|---|
status_code | int |
HTTP status code to return. |
detail | Any (optional) |
Body of the error response. Can be a string, dict, list, or any serializable value. |
headers | dict[str, Any] (optional) |
Custom headers to include in the response. |
Basic Usage¶
Raise a simple error¶
from ravyn import Ravyn, Gateway, get
from ravyn.contrib.responses.shortcuts import abort
@get()
async def not_found() -> None:
abort(404)
app = Ravyn(routes=[Gateway("/item", not_found)])
Result:
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
Not Found
Add a custom message¶
@get()
async def forbidden() -> None:
abort(403, "You cannot access this resource.")
Result:
HTTP/1.1 403 Forbidden
Content-Type: text/plain; charset=utf-8
You cannot access this resource.
Return structured JSON errors¶
@get()
async def invalid() -> None:
abort(400, {"error": "Invalid input", "field": "email"})
Result:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{"error": "Invalid input", "field": "email"}
This is particularly useful in APIs or JSON driven endpoints.
Add custom headers¶
@get()
async def blocked() -> None:
abort(403, "Access denied", headers={"X-Reason": "Policy Restriction"})
Result:
HTTP/1.1 403 Forbidden
X-Reason: Policy Restriction
Content-Type: text/plain; charset=utf-8
Access denied
Behavior Details¶
- When
detail
is a dict or list,abort()
automatically wraps it in aJSONResponse
. - When
detail
is a string, it uses a plainResponse
. - When
detail
isNone
, it returns the standard HTTP phrase for that status code (e.g."Not Found"
,"Bad Request"
). - For
204
or304
responses, Ravyn automatically sends no body, respecting HTTP semantics.
Integration with custom exception handlers¶
You can still register your own exception handlers if you want full control:
from ravyn import Ravyn, Request
from ravyn.responses import JSONResponse
from ravyn.exceptions import HTTPException
async def custom_http_exception(request: Request, exc: Exception):
return JSONResponse({"detail": exc.detail}, status_code=exc.status_code)
app = Ravyn(exception_handlers={HTTPException: custom_http_exception})
Now abort(401, "Unauthorized")
will trigger your custom handler and return a JSON response automatically.
Example: API-style Errors¶
Here's a full working example showing abort()
in a small API app.
from ravyn import Ravyn, Gateway, Request, get
from ravyn.contrib.responses.shortcuts import abort
@get()
async def create_user(request: Request) -> dict:
data = await request.json()
if "email" not in data:
abort(422, {"error": "Missing field", "field": "email"})
return {"message": "User created"}
@get()
async def forbidden_zone() -> None:
abort(403, "This endpoint is restricted.")
app = Ravyn(
routes=[
Gateway("/users", create_user),
Gateway("/admin", forbidden_zone),
]
)
Example outputs:
POST /users -> 422 {"error": "Missing field", "field": "email"}
GET /admin -> 403 "This endpoint is restricted."
Advanced: Raising Custom Responses¶
Since Ravyn's HTTPException
accepts a response
parameter, you can attach any Response subclass directly:
from ravyn import get
from ravyn.responses import HTMLResponse
from ravyn.exceptions import HTTPException
@get()
async def maintenance() -> HTTPException:
html = "<h1>Service temporarily unavailable</h1>"
response = HTMLResponse(html, status_code=503)
raise HTTPException(status_code=503, response=response)
This bypasses the default text or JSON logic entirely.
Summary¶
Use Case | Behavior |
---|---|
abort(404) |
Returns 404 with "Not Found" |
abort(401, "Unauthorized") |
Returns text message |
abort(400, {"error": "Invalid"}) |
Returns JSON |
abort(403, "Blocked", {"X-Blocked": "1"}) |
Adds custom headers |
abort(204) |
No content body |
Custom Response in HTTPException |
Full control |