简体   繁体   English

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

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

I develop with FastApi, and want to contain traceback info in response when error occur;我使用 FastApi 进行开发,并希望在发生错误时包含回溯信息以作为响应;
To do so, I define exception handlers in exception_handler.py :为此,我在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,
    )

And attach those handler to fastappi app instance in server.py :并将这些处理程序附加到server.py中的 fastappi 应用程序实例:

server.py is where I create app instance and attach extra function to it like middlewares or exception handlers. 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)

The problem is, when exception was raised, traceback message return by format_exc() is None ;问题是,当引发异常时, format_exc()返回的回溯消息是None
But when I used str(exc) like the annotated code, I got the exception info properly but of course without traceback info.但是当我像带注释的代码一样使用str(exc)时,我正确地获得了异常信息,但当然没有回溯信息。

It will not work because the exception handler receives the exception as parameter instead of catching the exception itself, meaning that there is no stacktrace in this case.它不起作用,因为异常处理程序接收异常作为参数而不是捕获异常本身,这意味着在这种情况下没有堆栈跟踪。

If you want to have the stacktrace, you should create a middleware or a custom API router that will actually capture the exception and return the message the way you want.如果您想拥有堆栈跟踪,您应该创建一个中间件或自定义 API 路由器,它们将实际捕获异常并以您想要的方式返回消息。 I usually prefer to use a custom API Route instead of using middleware because it is more explicit and gives you more flexibility.我通常更喜欢使用自定义 API 路由而不是使用中间件,因为它更明确并为您提供更大的灵活性。

You can write something like this你可以写这样的东西

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

Then you override the default route handler from fastapi然后你从 fastapi 覆盖默认路由处理程序

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

It should give you want you want它应该给你想要的

There's always format_exception , which takes an explicit exception argument, rather than grabbing the current one from sys.exc_info() .总是有format_exception ,它采用显式异常参数,而不是从sys.exc_info()获取当前异常参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM