python-3.x 在Fast API和自定义异常的自定义消息中捕获一般异常

piztneat  于 2023-05-19  发布在  Python
关注(0)|答案(1)|浏览(122)

我正在尝试在FastAPI中实现异常处理。
1.我有Try沿着Exception块,在其中我试图实现Generic Exception,如果发生任何其他异常,而不是Try块中提到的HTTPExceptions。在一般异常中,我想以{“details”:“Actual Exception Details”}然而,在下面的实现中,即使Try中的任何异常被引发,它也会转到Except块并打印该异常。
1.我尝试阻止特定的异常,我试图有一个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)
nhaq1z21

nhaq1z211#

您可以使用Pydantic的conintconstr来限制参数允许值的范围,如果包含在文档中,也将提供必要的信息。它们将自动生成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内部可以抛出什么异常),但您不应该自己处理(如果抛出自定义异常,则为use FastAPI's built-in exception handling to handle it)。
如果你想更进一步,这是你经常做的事情,把生成Student对象移到一个单独的依赖项中:

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)

这样,你的依赖项就可以在任何你需要从URL参数中获取学生的地方被重用。

{
  detail: [
    {
      loc: [
        "query",
        "rank"
      ],
      msg: "ensure this value is greater than 0",
      type: "value_error.number.not_gt",
      ctx: {
        limit_value: 0
      }
    }
  ]
}

相关问题