You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让FastAPI自定义错误响应的状态码与实际响应状态码一致?

解决FastAPI响应状态码与BadResponse模型不一致的问题

问题根源:直接返回Pydantic模型时,FastAPI默认使用200作为响应状态码,不会读取模型内部的status_code字段值。以下是几种可行的解决方式:

方法1:手动返回JSONResponse并指定状态码

直接利用FastAPI的JSONResponse,将模型转为字典后返回,同时把模型中的status_code作为响应状态码传入:

from fastapi import FastAPI, status, JSONResponse

app = FastAPI()

@app.get("/tmp")  # 注意路径需以/开头,修正原代码中的路径问题
def tmp():
    bad_resp = BadResponse.new(status_code=status.HTTP_404_NOT_FOUND, error="Not found")
    # 使用by_alias=True保证字段按驼峰式返回(匹配你的alias_generator配置)
    return JSONResponse(content=bad_resp.dict(by_alias=True), status_code=bad_resp.status_code)

方法2:自定义异常类+全局异常处理器

通过自定义异常并绑定处理器,实现抛出异常时自动返回标准化响应和对应状态码,更符合FastAPI的异常处理逻辑:

from fastapi import FastAPI, status, HTTPException, Request
from fastapi.responses import JSONResponse

# 自定义异常类
class BadResponseException(HTTPException):
    def __init__(self, status_code: int, error: ErrorDescription):
        super().__init__(status_code=status_code)
        self.error = error

# 注册全局异常处理器
@app.exception_handler(BadResponseException)
async def bad_response_handler(request: Request, exc: BadResponseException):
    resp = BadResponse.new(status_code=exc.status_code, error=exc.error)
    return JSONResponse(content=resp.dict(by_alias=True), status_code=exc.status_code)

# 路由中使用
@app.get("/tmp")
def tmp():
    raise BadResponseException(status_code=status.HTTP_404_NOT_FOUND, error="Not found")

方法3:封装工具函数减少重复代码

如果多个路由都需要返回BadResponse,可以封装一个工具函数统一处理:

from fastapi import JSONResponse

def create_bad_response(bad_resp: BadResponse):
    return JSONResponse(content=bad_resp.dict(by_alias=True), status_code=bad_resp.status_code)

# 路由调用
@app.get("/tmp")
def tmp():
    bad_resp = BadResponse.new(status_code=status.HTTP_404_NOT_FOUND, error="Not found")
    return create_bad_response(bad_resp)

内容的提问来源于stack exchange,提问作者haku

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 14:24:18