Catching general exceptions in Fast API and Custom Message for custom exceptions

问题描述 投票:0回答:1

我正在尝试在 FastAPI 中实现异常处理。

  1. 我有 Try 和 Exception 块,如果发生除 Try Block 中提到的 HTTPExceptions 之外的任何其他异常,我将在其中尝试实现通用异常。 在一般异常中,我想以格式打印实际异常的详细信息 { "details": "Actual Exception Details" } 然而,在下面的实现中,即使在 Try 中引发了任何异常,它也会转到 Except 块并打印该异常。

  2. 我尝试阻止特定的异常,我正在尝试拥有一个 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)
python-3.x exception error-handling try-catch fastapi
1个回答
1
投票

您可以使用 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)


© www.soinside.com 2019 - 2024. All rights reserved.