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

FastAPI端点多状态码JSONResponse返回及测试问题排查

FastAPI 实现多状态码返回的解决方案

先解决你遇到的 UnboundLocalError 问题

这个错误通常是因为你在正常逻辑分支定义了response变量,但异常分支未定义就尝试返回它。比如这种错误写法:

@app.post("/division")
def division(data: dict):
    try:
        a = data["a"]
        b = data["b"]
        result = a / b
        response = JSONResponse(content={"result": result}, status_code=200)
    except ZeroDivisionError:
        # 这里未定义response就返回,触发UnboundLocalError
        return response
    return response

解决核心是:每个分支直接返回对应响应或抛出异常,不要依赖跨分支的变量。


方案一:使用FastAPI内置HTTPException(推荐)

FastAPI会自动将HTTPException转为标准JSON格式响应,无需手动构造JSONResponse,同时能精准返回指定状态码。

示例代码:

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

app = FastAPI()

@app.post("/division")
def division(data: dict):
    # 触发422:参数缺失或格式错误
    if "a" not in data or "b" not in data:
        raise HTTPException(status_code=422, detail="缺少必要参数a或b")
    
    try:
        a = float(data["a"])
        b = float(data["b"])
    except ValueError:
        raise HTTPException(status_code=422, detail="参数必须为有效数字")
    
    # 触发500:除数为0
    if b == 0:
        raise HTTPException(status_code=500, detail="除数不能为0")
    
    # 触发404:模拟业务场景下的资源未找到
    if a < 0:
        raise HTTPException(status_code=404, detail="负数被除数无对应处理逻辑")
    
    # 正常返回200
    result = a / b
    return JSONResponse(content={"result": round(result, 2)}, status_code=200)

方案二:自定义异常+全局异常处理器

如果需要统一所有错误响应的格式,可自定义异常类并绑定全局处理器:

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

app = FastAPI()

# 自定义异常类
class DivisionError(Exception):
    def __init__(self, status_code: int, detail: str):
        self.status_code = status_code
        self.detail = detail

# 全局异常处理器
@app.exception_handler(DivisionError)
async def division_error_handler(request: Request, exc: DivisionError):
    return JSONResponse(
        content={"error": exc.detail, "code": exc.status_code},
        status_code=exc.status_code
    )

@app.post("/division")
def division(data: dict):
    if "a" not in data or "b" not in data:
        raise DivisionError(status_code=422, detail="缺少参数a/b")
    
    try:
        a = float(data["a"])
        b = float(data["b"])
    except ValueError:
        raise DivisionError(status_code=422, detail="参数不是有效数字")
    
    if b == 0:
        raise DivisionError(status_code=500, detail="除数不能为0")
    
    if a < 0:
        raise DivisionError(status_code=404, detail="不支持负数被除数")
    
    result = a / b
    return JSONResponse(content={"result": round(result, 2)}, status_code=200)

关键注意事项

  1. 所有代码路径必须有明确的返回或异常抛出,避免变量未定义就使用
  2. 422状态码通常用于请求参数校验失败,FastAPI会自动为Pydantic模型校验失败返回422,如果你用字典接收参数则需要手动判断
  3. 500状态码建议用于服务器内部错误(比如除数为0),404用于业务层面的资源未找到场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 18:59:52