Skip to content
On this page

全局异常处理

程序会抛出各种各样的异常,暂且分为运行时异常用户自定义异常,当程序发生错误的时候,肯定不会希望给用户返回一个 Internal Server Error ,并且在调试的过程,如果只返回 Internal Server Error,那么也是一脸茫然,所以需要完善的处理异常。

定义异常类

涉及文件 app/common/exception.py

python
class APIException(Exception):  
    """ API 异常类 """  
    def __init__(self, code, msg):  
        self.code = code  
        self.msg = msg  
  
    def __repr__(self) -> str:  
        class_name = self.__class__.__name__  
        return f"{class_name}(error_code={self.code!r}, error_msg={self.msg!r})"  

APIException 顾名思义,就是我们调用 API 的时候,我们想要给出自定义的异常,里面也是包含了 code、msg。

定义异常处理器

涉及文件 app/common/error_handle.py

python
from starlette.requests import Request  
from starlette.responses import JSONResponse  
  
from app.common.exception import APIException  
from app.common.response import APIResponse, APICode  
  
  
async def http_error_handler(request: Request, exc: APIException) -> JSONResponse:  
    """ HTTP 异常处理 """    return JSONResponse(status_code=exc.code, content=APIResponse(code=exc.code, msg=exc.msg).dict())  
  
  
async def runtime_error_handler(request: Request, exc: Exception) -> JSONResponse:  
    """ 运行时异常处理 """    return JSONResponse(status_code=APICode.RUNTIME_ERROR.code, content=APIResponse(code=APICode.RUNTIME_ERROR.code, msg=APICode.RUNTIME_ERROR.msg).dict())

http_error_handler 是我们自己决定的异常,需要我们手动抛出异常后,会执行到这里。

runtime_error_handler 是未知的异常,全部统一拦截到此处。

它们全部返回 JSONResponse 对象。

绑定异常处理器

涉及文件 main.py

python
import os  
  
from fastapi import FastAPI  
  
from app.common.exception import APIException, RuntimeException  
from app.controller.user import UserController  
from app.common.error_handle import http_error_handler, runtime_error_handler  
  
app = FastAPI()  
  
app.include_router(UserController.get_router(), prefix='/api')  
  
app.add_exception_handler(APIException, http_error_handler)  
app.add_exception_handler(Exception, runtime_error_handler)  
  
if __name__ == '__main__':  
    # 设置 ENV_FOR_DYNACONF 为 development    os.environ['ENV_FOR_DYNACONF'] = 'development'  
    # os.environ['ENV_FOR_DYNACONF'] = 'production'  
  
    import uvicorn  
  
    uvicorn.run('main:app', host='0.0.0.0', port=8000, reload=True)

Released under the MIT License.