我正在尝试在 FastAPI 中实现异常处理。
我有 Try 和 Exception 块,如果发生除 Try Block 中提到的 HTTPExceptions 之外的任何其他异常,我将在其中尝试实现通用异常。 在一般异常中,我想以格式打印实际异常的详细信息 { "details": "Actual Exception Details" } 然而,在下面的实现中,即使在 Try 中引发了任何异常,它也会转到 Except 块并打印该异常。
我尝试阻止特定的异常,我正在尝试拥有一个 CustomException 类,它可以打印自定义异常的详细信息以及异常名称。
@app.get("/school/studentclass")
async def get_student_class(id: int, stream: str, rank: int = 1):
try:
student = Student(id=id,stream=stream,rank=1)
if (student.id != 0):
if (student.stream is not None or student.stream != ''):
if(student.rank!= 0):
// Student Class is used to represent API Output : Student_Class_Name and Student_Class_Room and Student_Class_Teacher
studentClass = StudentClass()
// Processing Logic to get Student Class
return JSONResponse(content=studentClass)
else:
raise HTTPException(status_code = 422, detail = "Student Rank is not right", headers={"X-Error": "Student Rank is not right"})
else:
raise HTTPException(status_code = 422, detail="Student Stream is not right", headers={"X-Error": "Student Stream is not right"})
else:
raise HTTPException(status_code = 422, detail="Student Id is not right", headers={"X-Error": "Student Id is not right"})
except Exception as e:
raise HTTPException(status_code = 418, detail=str(e))
自定义异常类
class CustomException(Exception):
def __init__(self, name: str):
self.name = name
对于第二个问题,我尝试如下实现,但它不是这样工作的
else:
raise HTTPException(status_code = 422, detail = CustomException(name = "Invalid Student Rank"), headers={"Error": "Invalid Student Rank"})
错误处理如下:
@app.exception_handler(StarletteHTTPException)
async def custom_http_exception_handler(request, exc):
print(f"HTTP Error: {repr(exc)}")
return await http_exception_handler(request, exc)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
print(f"Invalid Data: {exc}")
return await request_validation_exception_handler(request, exc)
您可以使用 Pydantic 中的
conint
和 constr
来限制参数的允许值范围,如果包含在文档中,这也将提供必要的信息。它们会自动生成 422 错误,其中包含有关值太低的描述性信息。
我还强烈建议遵循“早点返回”规则(即使你在这里使用例外)。然而,在这种情况下,我们可以让 pydantic 为我们做所有的验证,如果提交的值不符合要求,FastAPI 会自动返回 422 错误:
from pydantic import constr, conint
@app.get("/school/studentclass")
async def get_student_class(id: conint(gt=0), stream: constr(min_length=1), rank: conint(gt=0) = 1):
student = Student(id=id, stream=stream, rank=rank)
# Student Class is used to represent API Output : Student_Class_Name and Student_Class_Room and Student_Class_Teacher
student_class = StudentClass()
# Processing Logic to get Student Class
return {"content": student_class) # I'd also recommend avoiding "content" here as it conveys no meaning at all
我不知道你最后的
except
是为了捕获什么(即可以在里面抛出什么异常- 在异常处理中处理它)。如果您想更进一步,这是您经常做的事情,请将生成 Student 对象改为单独的依赖项:
Student
这样你的依赖就可以在任何你需要从 URL 参数中获取学生的地方重复使用。
from pydantic import constr, conint
from typing import Annotated
async def student_from_url_id(id: conint(gt=0), stream: constr(min_length=1), rank: conint(gt=0) = 1):
return Student(id=id, stream=stream, rank=rank)
@app.get("/school/studentclass")
async def student_class_endpoint(student: Annotated[Student, Depends(student_from_url_id)])
student_class = StudentClass()
# Processing Logic to get Student Class
return {"content": student_class)