簡體   English   中英

FastApi:使用 add_exception_handler 時 traceback.exc_format 不返回

[英]FastApi : traceback.exc_format return none when using add_exception_handler

我使用 FastApi 進行開發,並希望在發生錯誤時包含回溯信息以作為響應;
為此,我在exception_handler.py中定義了異常處理程序:

from fastapi.responses import JSONResponse
from fastapi import status
from fastapi import FastAPI, Request
from traceback import format_exc, print_exc


def general_exception_handler(req: Request, exc: Exception):
    '''
    Exception handler for unspecified exceptions 
    '''
    
    tracback_msg = format_exc() 
    return JSONResponse(
        {
            "code": status.HTTP_500_INTERNAL_SERVER_ERROR,
            "message": f"error info: {tracback_msg}",
            # "message": f"error info: {str(exc)}",
            "data": "",
        },
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
    )

並將這些處理程序附加到server.py中的 fastappi 應用程序實例:

server.py是我創建應用程序實例並為其附加額外功能(如中間件或異常處理程序)的地方。

from core import router # api routers are defined in router.py
from fastapi import FastAPI
from core.exception_handler import general_exception_handler


app = FastAPI(
    debug=False,
    docs_url=None,
    redoc_url=None
)


# attach exception handler to app instance
app.add_exception_handler(Exception, general_exception_handler)

# include routers to app intance
app.include_router(router.router)

問題是,當引發異常時, format_exc()返回的回溯消息是None
但是當我像帶注釋的代碼一樣使用str(exc)時,我正確地獲得了異常信息,但當然沒有回溯信息。

它不起作用,因為異常處理程序接收異常作為參數而不是捕獲異常本身,這意味着在這種情況下沒有堆棧跟蹤。

如果您想擁有堆棧跟蹤,您應該創建一個中間件或自定義 API 路由器,它們將實際捕獲異常並以您想要的方式返回消息。 我通常更喜歡使用自定義 API 路由而不是使用中間件,因為它更明確並為您提供更大的靈活性。

你可以寫這樣的東西

class MyRoute(APIRoute):
    def get_route_handler(self) -> Callable:
        original_route_handler = super().get_route_handler()

        async def custom_route_handler(request: Request) -> Response:
            try:
                return await original_route_handler(request)
            except Exception as exc:
                tracback_msg = format_exc()
                # your return goes here

        return custom_route_handler

然后你從 fastapi 覆蓋默認路由處理程序

app = FastAPI()
app.router.route_class = MyRoute

它應該給你想要的

總是有format_exception ,它采用顯式異常參數,而不是從sys.exc_info()獲取當前異常參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM