使用FastAPI的HTTPException时如何传递自定义reason?
问题分析与解决方案
问题描述
我用FastAPI开发了一个API,触发错误时会抛出如下异常:
raise HTTPException(status_code=404, detail="There is no file to created a zip package. Check device name.")
可以看到我已经填写了detail字段,但查看请求端日志时却显示:
[2023-12-15 00:16:30,954]:[DEBUG]:[file_operations]:download_log_file() error: 404 reason:Not Found
为什么reason显示的是"Not Found"?我的代码有问题吗?捕获该日志的请求端相关代码如下:
try: r = self.get( self.base_url + "/downloadlog", headers=headers, params=params, timeout=100, ) # Check if the request was successful (status code 200) if r.status_code == 200: ... ... else: print(f"download_log_file() error: {r.status_code} reason:{r.reason}") error_response = { "error": f"HTTP error occurred: {r.status_code} {r.reason}", "request_id": request_id, } raise HTTPException( status_code=r.status_code, detail=error_response )
原因解析
r.reason的本质:r.reason是HTTP状态码对应的标准默认描述(比如404对应"Not Found"),它来自HTTP响应的状态行,和FastAPI返回的自定义detail字段完全是两回事。- 自定义错误信息的位置:FastAPI抛出
HTTPException时,你设置的detail会被放在响应体的JSON数据里,而不会修改状态行的reason短语。你当前的请求端代码只读取了r.reason,没有解析响应体,所以看不到自定义的错误内容。
修复方案
要获取你在FastAPI中设置的自定义detail,需要解析响应的JSON内容,修改请求端的错误处理逻辑:
else: # 读取响应体中的自定义错误信息 try: error_detail = r.json().get("detail", r.reason) except ValueError: # 若响应不是JSON格式, fallback到默认reason error_detail = r.reason print(f"download_log_file() error: {r.status_code} reason:{error_detail}") error_response = { "error": f"HTTP error occurred: {r.status_code} {error_detail}", "request_id": request_id, } raise HTTPException( status_code=r.status_code, detail=error_response )
另外,你在FastAPI端抛出HTTPException的写法是正确的,无需修改,响应体里确实会包含你设置的自定义detail内容。
内容的提问来源于stack exchange,提问作者user1657666
相关产品推荐
相关产品推荐

