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

FastAPI FileResponse异常处理在CloudRun上失效问题求助

问题原因分析

当前代码的try-except块无法捕获异常,核心原因是FileResponse在路由函数返回后,才会在其__call__方法中执行文件状态校验(如os.stat),这部分逻辑不在路由函数的try-except作用域内,因此抛出的异常会直接触发500内部服务器错误。

解决方案

在创建FileResponse前,主动完成文件存在性和读取权限的校验,将异常捕获逻辑提前到路由函数的try块内。由于FastAPI是异步框架,需用asyncio.to_thread包装同步文件操作,避免阻塞事件循环。

修改后的代码

import os
import asyncio
from fastapi import HTTPException, status, Depends
from fastapi.responses import FileResponse
# 导入你的自定义模块
from your_module import router, UsuarioModel, get_current_user

@router.get('/download/{file_name}', 
            status_code=status.HTTP_200_OK,
            description='Download do arquivo tratado',
            summary='Esta rota voce realiza o download do arquivo processado')
async def imagelabel(file_name: str, usuario_logado: UsuarioModel = Depends(get_current_user)):
    file_path = f'/app/downloads/{file_name}'
    
    try:
        # 用线程池包装同步文件操作,避免阻塞异步事件循环
        await asyncio.to_thread(lambda: open(file_path, 'rb').close())
        
        return FileResponse(file_path)
    except FileNotFoundError:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Arquivo não foi encontrado: {file_name}"
        )
    except PermissionError:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail=f"Permissão negada para o arquivo: {file_name}"
        )

关键改进点

  1. 提前文件校验:通过open(file_path, 'rb').close()一次性验证文件存在性和读取权限,覆盖FileNotFoundError和PermissionError场景。
  2. 异步兼容:使用asyncio.to_thread将同步IO操作转移到线程池,符合FastAPI异步运行模型,避免服务阻塞。
  3. 错误信息优化:直接使用传入的file_name构造提示信息(原error.filename在部分环境下可能不可靠)。

CloudRun额外注意事项

  • CloudRun的本地文件系统是临时的,若需持久化存储文件,建议替换为Cloud Storage,通过GCS SDK获取文件流后返回StreamingResponse。
  • 确保CloudRun服务账号对/app/downloads目录有读取权限(若使用本地存储),或对Cloud Storage Bucket配置了相应权限。

内容的提问来源于stack exchange,提问作者Rodrigo Augusto Martins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 10:20:39