在 FastAPI 中自定义异常处理器以统一返回 JSON 格式错误,主要通过`@app.exception_handler`装饰器注册自定义异常处理函数。开发者可以定义继承自 Exception 的自定义异常类,或使用框架内置的`HTTPException`和`RequestValidationError`。在处理函数中,实例化`JSONResponse`对象,设定统一的状态码(如 200 或 400)和包含 code、msg、data 字段的标准 JSON 结构。此外,还需覆盖默认的请求验证异常处理器,确保参数错误也遵循同一返回格式,从而实现全局统一的错误响应管理,提升前后端交互的规范性。
request body json 格式错误_全面拥抱 FastApi — 优雅的返回异常错误
本文介绍了如何在 FastAPI 中优雅地处理和返回错误,包括自定义异常类、重写默认异常类,特别是针对请求验证异常和 HTTPException 的处理。通过示例展示了如何将请求体包含在异常响应中,便于开发和调试。点击"Python 编程与实战",选择“置顶公众号”第一时间获取 Python 技术干货!在开发接口或者服务的时候,经常会遇到需要给客户端返回异常错误例如:用户操作权限不够 参数错误 请求的资源不存在.. 众所周知,因客户端或调用方的原因导致出错的,返回的状态码是以 4 开头的 (400~499) 比如常见的 404 Not Found, 资源不存在 为了直观友好的给客户端返回错误,在 FastApi 中一般使用 HTTPException fromfastapi import FastAPI, HTTPExceptionapp=FastAPI()items={"foo":"The Foo Wrestlers"}@app.get("/items/{item_id}")async defread_item(item_id: str):ifitem_idnotinitems:raiseHTTPException(status_code=404,detail="Item not found")return{"item": items[item_id]} 一键获取完整项目代码 当遇到用户请求异常的时候,可以选择用 raise 将异常抛出去 抛出异常,便立即会结束本次请求,并将 HTTP 错误从 HTTPException 发送到客户端或浏览器 比如:在浏览器中输入 http://127.0.0.1:8000/items/jerry 由于 jerry 并不在 items 中,浏览器便会收到 404 以及一个 json 格式的 response 注意:这个 json 由 FastAPI 自动处理并转换的。自定义异常类 和 starlette 源码中处理异常一样,你也可以自定义一个异常处理类定义的异常处理类,使用@app.exception_handler() 支持在 FastAPI 中全局使用该异常类 fromfastapi import FastAPI, Requestfrom fastapi.responses import JSONResponseclass UnicornException(Exception): def __init__(self, name: str):self.name=nameapp=FastAPI()@app.exception_handler(UnicornException)async def unicorn_exception_handler(request: Request, exc: UnicornException):returnJSONResponse(status_code=418,content={"message": f"Oops! {exc.name} did something. There goes a rainbow"}, ) 一键获取完整项目代码 在路由函数中,使用该类 @app.get("/unicorns/{name}")async defread_unicorn(name: str):ifname=="yolo":raiseUnicornException(name=name)return{"unicorn_name": name} 一键获取完整项目代码 运行服务后,请求服务路径/unicorns/yolo 在客户端就能收到一个提示友好,并事先定义好状态码 418 的提示错误
处理错误
处理错误 某些情况下,需要向使用你的 API 的客户端返回错误提示。这里所谓的客户端包括前端浏览器、他人的代码、物联网设备等。你可能需要告诉客户端:客户端没有执行该操作的权限 客户端没有访问该资源的权限 客户端要访问的项目不存在 等等 遇到这些情况时,通常要返回 4XX(400 至 499)HTTP 状态码。这与表示请求成功的 2XX(200 至 299)HTTP 状态码类似。那些"200"状态码表示某种程度上的“成功”。而 4XX 状态码表示客户端发生了错误。大家都知道「404 Not Found」错误,还有调侃这个错误的笑话吧?使用 HTTPException¶ 向客户端返回 HTTP 错误响应,可以使用 HTTPException。导入 HTTPException¶ Python 3.10+ fromfastapiimportFastAPI,HTTPExceptionapp=FastAPI()items={"foo":"The Foo Wrestlers"}@app.get("/items/{item_id}")asyncdefread_item(item_id:str):ifitem_idnotinitems:raiseHTTPException(status_code=404,detail="Item not found")return{"item":items[item_id]} 在代码中触发 HTTPException¶ HTTPException 是额外包含了和 API 有关数据的常规 Python 异常。因为是 Python 异常,所以不能 return,只能 raise。这也意味着,如果你在路径操作函数里调用的某个工具函数内部触发了 HTTPException,那么路径操作函数中后续的代码将不会继续执行,请求会立刻终止,并把 HTTPException 的 HTTP 错误发送给客户端。在介绍依赖项与安全的章节中,你可以更直观地看到用 raise 异常代替 return 值的优势。本例中,客户端用不存在的 ID 请求 item 时,触发状态码为 404 的异常:Python 3.10+ fromfastapiimportFastAPI,HTTPExceptionapp=FastAPI()items={"foo":"The Foo Wrestlers"}@app.get("/items/{item_id}")asyncdefread_item(item_id:str):ifitem_idnotinitems:raiseHTTPException(status_code=404,detail="Item not found")return{"item":items[item_id]} 响应结果¶ 请求为 http://example.com/items/foo(item_id 为"foo") 时,客户端会接收到 HTTP 状态码 200 及如下 JSON 响应结果:
FastAPI 异常处理:处理 HTTP 错误、自定义全局异常和覆盖请求校验异常
FastAPI 异常处理:处理 HTTP 错误、自定义全局异常和覆盖请求校验异常 通过具体示例,您将学会如何使用 HTTPException 处理 API 错误,如何创建自定义异常及其处理器,以及如何在 FastAPI 中覆盖 RequestValidationError 和 HTTPException。掌握这些技巧,能帮助您提升 API 的稳定性与用户体验。FastAPI 异常处理:处理 HTTP 错误、自定义全局异常和覆盖请求校验异常 1 参数 detail 传递更多 HTTPException 的信息 三 覆盖框架默认异常处理 1 覆盖请求验证异常 RequestValidationError 2 覆盖 `HTTPException` 异常处理器 3 请求体 `body` 数据格式可使用 `RequestValidationError` 覆盖 4 划重点 七 参考 以下示例中使用的 Python 版本为 Python 3.10.15,FastAPI 版本为 0.115.4。一 HTTPException 示例 fromfastapiimportFastAPI,HTTPException app=FastAPI()items={"foo":"Hello world!"}@app.get("/items01/{item_id}")asyncdefread_item(item_id:str):ifitem_idnotinitems:raiseHTTPException(status_code=404,detail={"error":"Item not found","item_id":item_id})return{"item":items[item_id]} 一键获取完整项目代码 python 1 2 3 4 5 6 7 8 9 10 11 客户端请求的 item_id 不存在时,触发 404 异常,HTTPException 是包含 API 数据的常规 Python 异常,不能 return,只能 raise。触发时,FastAPI 会终止路径操作函数的执行,并将错误返回给客户端。$ uvicorn chapter22:app--reload 一键获取完整项目代码 shell 1 在 SwaggerUI 中可以查看在线文档:http://127.0.0.1:8000/docs。1 参数 detail 传递更多 HTTPException 的信息 触发 HTTPException 时,可以通过 detail 传递任何可转换为 JSON 的值,如 str、dict、list 等,FastAPI 会自动转换为 JSON。2 参数 headers 自定义 HTTPException 的响应头 在某些场景下,需为 HTTP 错误添加自定义响应头,如出于安全考虑。通常不需要直接使用响应头,但高级应用场景中需添加自定义头。
四、Python 框架篇:FastApi-错误处理
四、Python 框架篇:FastApi-错误处理 在上篇文章 FastApi-响应模型中,我们强调的是接口对外输出结构应该一致,所以即便参数错误应该输出以下结构:{ "code":-1, "msg":"具体错误信息", "data": null } python 按照官方文档说法,我们需要自定义错误处理器,并以此来覆盖框架默认的异常处理器,参数验证错误处理器默认走的 RequestValidationError,所以覆盖它就行,下面是实现步骤 (2) 自定义处理器 新建包 errors,并新增文件 validation_error.py,文件内容如下:fromfastapiimportRequest, status fromfastapi.exceptionsimportRequestValidationError fromfastapi.responsesimportJSONResponse fromparameterimporthttp_resp fromfastapi.encodersimportjsonable_encoder asyncdefvalidationExceptionHandler(request: Request, exc: RequestValidationError): """ 自定义参数验证异常错误""" print("自定义参数验证异常错误") errMsg ="" forerrorinexc.errors(): errMsg +=".".join(error.get("loc")) +":"+ error.get("msg") +";" # 这里 response.ResponseFail 是上篇文章中的内容 returnJSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder(http_resp.ResponseFail(errMsg))) python 在包 errors/__init__.py 引用,并封装统一注册方法:fromfastapiimportFastAPI fromvalidation_errorimportvalidationExceptionHandler fromfastapi.exceptionsimportRequestValidationError defregisterCustomErrorHandle(server: FastAPI): """ 统一注册自定义错误处理器""" # 注册参数验证错误,并覆盖模式 RequestValidationError server.add_exception_handler(RequestValidationError, validationExceptionHandler)
FAQ
FastAPI 中如何捕获所有未处理的异常?
可以通过注册`@app.exception_handler(Exception)`来兜底捕获所有未被捕获的 Python 异常,但需注意这会吃掉所有异常,包括开发环境的逻辑错误。
为什么要覆盖 RequestValidationError?
因为参数验证错误默认走的 RequestValidationError,覆盖它可以确保参数错误也输出统一的 code、msg、data 结构,而不是默认的详细验证信息。
HTTPException 和自定义异常有什么区别?
HTTPException 是 FastAPI 内置的用于返回 HTTP 错误的异常,而自定义异常允许开发者定义业务特定的错误类型,并通过处理器统一格式化返回。