Handling Errors
starlette-context provides several error types that help identify and handle issues in your application.
ContextDoesNotExistError
This is the most common error you’ll encounter, raised when you try to access the context object outside of a request-response cycle.
Common Causes
1. Context Not Created
The most basic cause is trying to use the context object without adding one of the context middlewares to your application.
# This will fail with ContextDoesNotExistError
from starlette_context import context
value = context["key"] # Error!
Make sure you’ve added either ContextMiddleware or RawContextMiddleware to your application:
from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette_context.middleware import ContextMiddleware
app = Starlette(middleware=[Middleware(ContextMiddleware)])
2. Incorrect Middleware Order
The order of middlewares matters. The context is only available after the context middleware has processed the request and before it processes the response:
class FirstMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
# Can't access context here!
return await call_next(request)
class SecondMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
# Context is available here
response = await call_next(request)
# Context is still available here
return response
middlewares = [
Middleware(ContextMiddleware), # Creates context
Middleware(FirstMiddleware), # Can't use context (runs before ContextMiddleware)
Middleware(SecondMiddleware), # Can use context (runs after ContextMiddleware)
]
For more details on middleware execution order, see Starlette issue #479.
3. Outside Request-Response Cycle
The context is only available during the request-response cycle. It doesn’t persist after the response is sent:
@app.route("/")
async def handler(request):
context["value"] = "test"
return JSONResponse({"message": "OK"})
# After the response is sent:
# context["value"] # Would raise ContextDoesNotExistError
This applies to:
Logging outside of request handlers
Testing code that checks context after a request completes
Note on Background Tasks: Context may be available in background tasks due to Python’s ContextVar inheritance (PEP 567), but this is not guaranteed across all middleware types and Starlette versions. With RawContextMiddleware, background tasks run inside the middleware’s context manager, so context is reliably available. With ContextMiddleware (which uses BaseHTTPMiddleware), background tasks may run after the context has been reset, and availability depends on ContextVar inheritance to spawned tasks. To be safe, explicitly copy context data and pass it to background tasks. See the FastAPI Integration section for the recommended pattern.
Safe Access
Use context.exists() to check if the context is available before accessing it:
def log_with_context(message):
if context.exists():
logger.info(f"{message}", extra=context.data)
else:
logger.info(f"{message}")
For testing, either:
Return context data in the response:
return JSONResponse(context.data)Use the
request_cycle_contextcontext manager in tests:
from starlette_context import request_cycle_context, context
def test_with_context():
with request_cycle_context({"initial": "value"}):
context["test"] = "value"
assert context["test"] == "value"
MiddleWareValidationError
This error is raised when a plugin encounters invalid data and needs to return an error response. It’s typically used within plugin implementations:
from starlette.responses import JSONResponse
from starlette_context.errors import MiddleWareValidationError
async def process_request(self, request):
auth_header = request.headers.get("Authorization")
if not auth_header:
error_response = JSONResponse(
{"error": "Missing authorization header"},
status_code=401
)
raise MiddleWareValidationError(
"Missing auth header",
error_response=error_response
)
return auth_header
When this error is raised in a plugin, the middleware will catch it and return the provided error response.
ConfigurationError
This error is raised when there’s an issue with the configuration of the middleware or plugins:
from starlette_context.errors import ConfigurationError
# Raised when a plugin instance is invalid
if not isinstance(plugin, Plugin):
raise ConfigurationError(f"Plugin {plugin} is not a valid instance")
This is typically an issue you’ll encounter during development when setting up the middleware incorrectly.