全局异常/错误捕获

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from fastapi import FastAPI
from starlette.responses import JSONResponse

async def exception_not_found(request, exc):
    return JSONResponse({
        "code": exc.status_code,
        "error": "没有定义这个请求地址"},
        status_code=exc.status_code)

exception_handlers = {
    404: exception_not_found,
}

app = FastAPI(exception_handlers=exception_handlers)


if __name__ == "__main__":
    import uvicorn
    import os

    app_modeel_name = os.path.basename(__file__).replace(".py", "")
    print(app_modeel_name)
    uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)

  • 运行结果返回
# 达到预期效果
{
    "code": 404,
    "error": "没有定义这个请求地址"
}

-- 尝试方法2

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from fastapi import FastAPI
from starlette.responses import JSONResponse
from starlette.exceptions import HTTPException as StarletteHTTPException

async def exception_not_found(request, exc):
    return JSONResponse({
        "code": exc.status_code,
        "error": "没有定义这个请求地址"},
        status_code=exc.status_code)

app = FastAPI()
app.add_exception_handler(StarletteHTTPException, exception_not_found)

if __name__ == "__main__":
    import uvicorn
    import os

    app_modeel_name = os.path.basename(__file__).replace(".py", "")
    print(app_modeel_name)
    uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
  • 运行结果返回
# 达到预期效果
{
    "code": 404,
    "error": "没有定义这个请求地址"
}
  • 尝试方法3
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from fastapi import FastAPI
from starlette.responses import JSONResponse
from starlette.exceptions import HTTPException as StarletteHTTPException

# 先创建 app 实例
app = FastAPI()

# 然后再使用装饰器(这时 app 已经定义了)
@app.exception_handler(StarletteHTTPException)
async def exception_not_found(request, exc):
    return JSONResponse({
        "code": exc.status_code,
        "error": "没有定义这个请求地址"},
        status_code=exc.status_code)

if __name__ == "__main__":
    import uvicorn
    import os

    app_modeel_name = os.path.basename(__file__).replace(".py", "")
    print(app_modeel_name)
    uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
  • 运行结果返回
# 达到预期效果
{
    "code": 404,
    "error": "没有定义这个请求地址"
}
  • 尝试方法4-中间件
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from fastapi import FastAPI, Request
from starlette.responses import JSONResponse
from starlette.middleware.base import BaseHTTPMiddleware

app = FastAPI()

class NotFoundMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        response = await call_next(request)
        if response.status_code == 404:
            return JSONResponse({
                "code": 404,
                "error": "没有定义这个请求地址"
            }, status_code=404)
        return response

app.add_middleware(NotFoundMiddleware)

if __name__ == "__main__":
    import uvicorn
    import os

    app_model_name = os.path.basename(__file__).replace(".py", "")
    print(app_model_name)
    uvicorn.run(f"{app_model_name}:app", host='127.0.0.1', reload=True)
  • 运行结果返回
# 达到预期效果
{
    "code": 404,
    "error": "没有定义这个请求地址"
}
  • 尝试方法5 - 使用路由通配符捕获所有未匹配路由
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from fastapi import FastAPI
from starlette.responses import JSONResponse
from starlette.routing import Route

app = FastAPI()

# 这个通配路由会捕获所有未匹配的路径
@app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"])
async def catch_all(request):
    return JSONResponse({
        "code": 404,
        "error": "没有定义这个请求地址"
    }, status_code=404)

if __name__ == "__main__":
    import uvicorn
    import os

    app_model_name = os.path.basename(__file__).replace(".py", "")
    print(app_model_name)
    uvicorn.run(f"{app_model_name}:app", host='127.0.0.1', reload=True)
  • 运行结果返回
# 没有达到预期效果
{
    "detail": [
        {
            "type": "missing",
            "loc": [
                "query",
                "request"
            ],
            "msg": "Field required",
            "input": null
        }
    ]
}
  • 方案6-重写默认的404响应(最彻底)
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from fastapi import FastAPI
from fastapi.responses import JSONResponse
from fastapi.exception_handlers import http_exception_handler
from starlette.exceptions import HTTPException as StarletteHTTPException

app = FastAPI()

@app.exception_handler(StarletteHTTPException)
async def custom_http_exception_handler(request, exc):
    if exc.status_code == 404:
        return JSONResponse({
            "code": exc.status_code,
            "error": "没有定义这个请求地址"
        }, status_code=404)
    # 其他HTTP异常保持默认处理
    return await http_exception_handler(request, exc)

# 注意:这个方案理论上可行,但需要确保没有其他中间件干扰
# 如果还是不行,使用方案1或方案2

if __name__ == "__main__":
    import uvicorn
    import os

    app_model_name = os.path.basename(__file__).replace(".py", "")
    print(app_model_name)
    uvicorn.run(f"{app_model_name}:app", host='127.0.0.1', reload=True)
  • 运行结果返回
# 达到预期效果
{
    "code": 404,
    "error": "没有定义这个请求地址"
}
posted @ 2026-05-19 07:22  是17阿哥呀  阅读(9)  评论(0)    收藏  举报