FastAPI猜字谜实战(6):日志与异常

这是系列的第六篇。前面几篇我一路靠 print 走过来,能跑是能跑,但真出了错,浏览器那边一片空白,控制台一堆原始堆栈,看着头大。这一篇我把调试输出正规化,再给整个后端加个兜底。

一、print 用多了,我自己都嫌乱

一开始我在每个接口里写几句 print,看看走到哪一步了。功能少还行,等接口多起来,我发现问题很大:

  • 没时间戳,不知道是哪一秒出的事;

  • 没级别,不知道是普通信息还是严重错误;

  • 不知道是哪一行打的,出了事翻半天找不到源头;

  • 没法按需关闭,正式跑起来了一堆调试信息还在那刷屏。

所以我决定,换成正规的 logging。

二、一行配置,日志立刻像样了

我在文件顶部配一次,之后全用 logging.info:

import logging

logging.basicConfig(

level=logging.INFO,

format="%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s",

)

这个 format 是我特意挑的,打出来一条日志,自带时间、级别、文件名、行号、内容 五样东西。之前那些 print 我全替换成了 logging.info,写法没变、只是换了个名字,可输出质量完全是两个世界。

级别设成 INFO,是为了平时开发能看见普通信息。想安静的时候,我可以临时把它调到 ERROR,那些 info 就不刷了,只留重要的。这就是 print 给不了我的开关。

三、顺手关掉访问日志的刷屏

配好 logging 后,我还发现一个很吵的东西:uvicorn 每收到一个请求,就在控制台打一行 GET /... 200 OK 这种访问日志。开发时我压根不需要它,反而盖住了我自己的业务日志。

我在启动时加了个参数把它关了:

uvicorn.run(app, host="0.0.0.0", port=8000, access_log=False)

关掉之后,那些每条请求的访问行没了,控制台清爽很多,只剩启动信息和我的 logging 输出。

四、真正让我头疼的是报错

日志规整了,可还有个更大的问题。比如详情接口去读一个根本不存在的会话文件,open 直接抛异常。没处理的话会怎样?

前端 fetch 收到的是一个残缺的、甚至空白的响应,页面上什么提示都没有,玩家一脸懵。而我控制台里蹦出来的,是一整段原生的 traceback,又长又难看。

我要的是:不管后端哪里出错,都别把内部堆栈甩给前端,而是老老实实返回一个统一的错误 JSON,同时把真正的错误给我记到日志里。

五、一个全局异常处理器兜住所有

FastAPI 给了我这个能力,就是异常处理器。我注册一个兜底的,捕获所有没被处理的异常:

from fastapi import Request

from fastapi.responses import JSONResponse

@app.exception_handler(Exception)

def handler_exception(request: Request, exception: Exception) -> JSONResponse:

把出事的网址和错误信息记到日志里,只有我开发者看得到

logging.error(f"处理异常:请求路径 {request.url},错误信息:{exception}")

给前端返回规范的 JSON 三件套

return JSONResponse(

status_code=500,

content={"code": 500, "message": "服务器内部错误请联系管理员", "data": None},

)

它的逻辑是:一旦哪个接口抛了我没接住的异常,就全汇到这来。我用 logging.error 记下来,然后返回一个 JSONResponse,状态码 500,内容却还是我那个 code / message / data 三件套格式。

这样前端永远拿到的都是规范的 JSON,它能认出 code 不是 200、然后把 message 显示给玩家,页面不会崩、不会一片空白。

六、验证:故意读一个不存在的会话

我起了服务,专门去访问一个乱写的 id,比如 /api/sessions/not-exist-123。那个文件根本不存在,接口里的 open 必然抛异常。

结果符合预期:

  • 后端 :我这边控制台看到一条 ERROR 级日志,带着请求路径和具体错误。

  • 前端 :收到的却是干净的 {code: 500, message: "服务器内部错误...", data: null},不是半截 HTML,也不是空白。

一点小说明:即使有了这个处理器,uvicorn 控制台还是会额外打一段原始堆栈,那是它自带的行为,我的处理器管不着。但它不影响前端拿到的那个干净 JSON,所以不用管它。

相关推荐
PythonFun1 小时前
如何生成Python50天系列学习互动网页课件
python·wps
垆边人似月.1 小时前
预处理与参数调优(让识别率从“能看”到“可用”)
开发语言·python·自然语言处理
gf13211111 小时前
python_高德地图驾车时长查询
数据库·python·mysql
镜子AI1 小时前
镜子AI技术实践:用 Python 做 GEO 答案的实体提及抽取与归一化(零依赖两阶段方案)
python·ai
I Am a robert girl1 小时前
从点到面:Superquadric 分解中“几何感知内点精修”的工程拆解
python·ransac·点云处理·三维感知·superquadric·几何基元拟合·内点判定
计算机毕业编程指导师1 小时前
计算机毕设推荐:基于深度学习的动物图像识别方法研究(Python+Django+PyTorch)
pytorch·python·深度学习·计算机·毕业设计·课程设计·图像识别
Java后端的Ai之路1 小时前
【AIAgent项目-AI生成PPT-09】灵活排版
前端·vue.js·人工智能·python·powerpoint
泡泡糖的中文规格书1 小时前
HDLbits 2.2 学习笔记 · 多路复用器
java·开发语言
John_Hui1 小时前
第 3 篇:配置 JDK 17 环境
java·开发语言·ubuntu