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

FastAPI数据库提交错误处理优化:状态码、错误信息及会话管理

FastAPI天气读数接口错误处理优化方案

针对你提出的三个问题,逐一给出解决方案及优化后的代码:

一、提取并返回实际错误信息

SQLAlchemy异常对象包含具体错误详情,可通过str(e)提取,但要注意避免泄露数据库敏感信息(如账号、地址),可以按需截取或格式化后返回。

二、返回符合规范的错误状态码

  • 若为服务器端数据库操作失败(如连接异常、事务错误),返回500 Internal Server Error;
  • 若为客户端提交数据不符合数据库约束(如sensor_id不存在、数值超出范围),返回400 Bad Request。
    FastAPI中使用HTTPException可以直接抛出指定状态码和描述的异常,框架会自动生成标准响应格式。

三、数据库会话的正确管理

  • 回滚:异常发生时必须执行回滚,避免会话残留未提交的脏数据;
  • 关闭会话:无论请求成功或失败,都需要关闭会话以释放数据库连接。推荐用finally块确保会话始终被关闭,或者使用上下文管理器简化操作。

优化后的完整代码

from fastapi import FastAPI, HTTPException
from sqlalchemy.exc import SQLAlchemyError
# 假设你已导入WeatherReading模型和session对象

app = FastAPI()

@app.post("/reading")
async def record_reading(
    sensor_id: int,
    fahrenheit: float,
    pressure: float,
    humidity: float,
    dew_point: float,
    battery: float
):
    weather_reading = WeatherReading(
        sensor_id=sensor_id,
        fahrenheit=fahrenheit,
        pressure=pressure,
        humidity=humidity,
        dew_point=dew_point,
        battery=battery
    )
    try:
        session.add(weather_reading)
        session.commit()
        return {"message": "reading added"}
    except SQLAlchemyError as e:
        session.rollback()
        # 提取错误信息,可根据实际情况过滤敏感内容
        error_detail = str(e).split("\n")[0]  # 只取错误首行避免冗余
        # 判断错误类型,区分客户端/服务器错误
        if "foreign key constraint" in str(e).lower() or "check constraint" in str(e).lower():
            raise HTTPException(status_code=400, detail=f"Invalid input: {error_detail}")
        else:
            raise HTTPException(status_code=500, detail=f"Database error: {error_detail}")
    finally:
        # 无论成功失败,确保会话关闭
        session.close()

补充说明

  • 使用finally块保证会话一定会被关闭,避免连接池耗尽;
  • 通过判断错误关键词区分客户端和服务器错误,返回更精准的状态码;
  • 错误信息做了简单截取,你可以根据实际需求调整格式化方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 21:13:21