ClientRequestError#
- exception safir.fastapi.ClientRequestError(message, location=None, field_path=None)#
Represents an error in a client request.
This is a base class for exceptions representing expected errors in client requests. Expected here means that the error should result in a 4xx HTTP error code with an error message in the body and do not represent a server failure that should produce alerts. It should normally be used in conjunction with the
client_request_error_handler
exception handler.Exceptions inheriting from this class should set the class variable
error
to a unique error code (normally composed of lowercase letters and underscores) for that error, and the class variablestatus_code
to the HTTP status code this exception should generate (if not 422, the default).- location#
The part of the request giving rise to the error. This can be set by catching the exception in the part of the code that knows where the data came from, setting this attribute, and re-raising the exception.
- field_path#
Field, as a hierarchical list of structure elements, within that part of the request giving rise to the error. As with
location
, can be set by catching and re-raising.
- Parameters:
message (
str
) – Error message, used as themsg
key in the serialized error.location (
Optional
[ErrorLocation
], default:None
) – The part of the request giving rise to the error. This may be omitted if the error message does not have meaningful location information, or to set this information via the corresponding attribute in a later exception handler.field_path (
Optional
[list
[str
]], default:None
) – Field, as a hierarchical list of structure elements, within thelocation
giving rise to the error. This may be omitted if the error message does not have meaningful location information, or to set this information via the corresponding attribute in a later exception handler.
Examples
This class is meant to be subclassed. For example:
from fastapi import status from safir.fastapi import ClientRequestError class UnknownUserError(ClientRequestError): error = "unknown_user" status_code = status.HTTP_404_NOT_FOUND
If the location of the error is known when it is raised, it can be passed to the constructor. If a given error message always stems from the same location information, override
__init__
of the corresponding child exception class to pass that location information to the parent constructor.More commonly, the location information is only known to the handler, but the exception will be raised by internal service code. In this case, do not specify
location
orfield_path
when raising the exception, and catch and re-raise the exception in the handler after adding additional location information. For instance:from safir.models import ErrorLocation @router.get("/info/{username}", response_model=UserInfo) async def get_info(username: str) -> UserInfo: try: return get_user_data(username) except UnknownUserError as e: e.location = ErrorLocation.path e.field_path = ["username"] raise
field_path
may be a hierarchical list of elements in a complex structure. For example, for a POST handler that accepts JSON and finds a problem in theaddress
key of theuser
field, setfield_path
to["user", "address"]
.Some errors, such as permission denied errors, will not have any meaningful associated location information. In this case, do not specify
location
orfield_path
.Notes
FastAPI uses a standard error model for internally-generated errors (mostly Pydantic validation errors), but doesn’t provide a facility to generate errors in the same format. Safir provides the
ErrorModel
Pydantic model, this class, and theclient_request_error_handler
exception handler to fill in the gap.This class records the necessary information to generate a FastAPI-compatible error structure and knows how to serialize itself in the same structure as
ErrorModel
via theto_dict
method. Theclient_request_error_handler
exception handler uses that facility to transform this exception into afastapi.responses.JSONResponse
with an appropriate status code.The FastAPI error serialization format supports returning multiple errors at a time as a list in the
detail
key. This functionality is not supported by this exception class.