高效优雅处理程序错误实战

点击python编程从入门到实践置顶 公众号重磅 python入门资料,第一时间送达javascript


                        

                                  仍是牛java


读完须要python

12
分钟

速读仅需 4 分钟程序员

/ python 生产实战 高效优雅处理程序错误 /web

今天,讨论一下程序中的错误处理。也许你会以为这个事没什么意思,处理错误的代码并不难写。但你想过没有,要把错误处理写好,并非件容易的事情。另外,任何一个稳定的程序中都会有大量的代码在处理错误,因此说,处理错误是程序中一件比较重要的事情。本篇咱们系统地了解一下错误处理的各类方式和相关实践。编程

错误是指致使系统不能按照用户意图工做的一切缘由、事件。在程序设计过程当中,因为某些错误的存在,导致程序没法正常运行,处理这些错误以使程序正确运行就称为错误处理。错误处理功能是衡量编译器性能的重要方面,它在帮助程序员尽快修改程序方面起到了很是重要的做用。api

1安全


   

程序错误类型微信

1.1闭包


   

语法错误

语法错误是由于源程序中不正确的代码产生的,即在编写程序时没有遵照语法(或词法)规则,书写了错误的语法代码,从而致使编译器没法正确解释源代码而产生的错误,一般是因为录入的错误引发的,它在词法分析或语法分析时检测出来。如“非法字符”、“括号不匹配”、“缺乏;”之类的错误。

1.2


   

语义错误

语义错误是指源程序中不符合语义规则的错误,即一条语句试图执行一条不可能执行的操做而产生的错误。语义错误有的在语义分析时检测处来,有的在运行时才能检测出来。如变量声明错误、做用域错误、数据存储区的溢出等错误。

1.3


   

逻辑错误

逻辑错误是指程序的运行结果和程序员的设想有出入时产生的错误。这类错误并不直接致使程序在编译期间和运行期间出现错误,可是程序未按预期方式执行,产生了不正确的运行结果,较难发现。这种错误只能经过分析结果,将结果与设计方案进行对比来发现。

2


   

HTTPException

咱们用 HTTPException 模块返回带错误信息的 Response。HTTPException 是一个普通的 Python 异常,同时带有与 API 访问有关的附加数据。

from fastapi import FastAPI, HTTPException
app = FastAPI()
items = {"book": "Learn Python"}

@app.get("/items/{item_id}")async def read_item(item_id: str): if item_id not in items:
raise HTTPException(status_code=404, detail="Item not found")
return {"item": items[item_id]}


3


   

添加自定义头信息

有时候针对 HTTP 错误,在一些场景下,咱们须要添加自定义头信息

from fastapi import FastAPI, HTTPException
app = FastAPI()
items = {"book": "Learn Python"}

@app.get("/items-header/{item_id}")async def read_item_header(item_id: str): if item_id not in items: raise HTTPException( status_code=404, detail="Item not found", headers={"X-Error": "error info"},
) return {"item": items[item_id]}


4


   

自定义异常处理器

在 fastapi 中借助 the same exception utilities from Starlette,咱们能够添加自定义异常处理器。假设咱们有个自定义异常 UnicornException,咱们想在全局范围内处理这个异常。借助 @app.exception_handler(),就能够实现咱们的目标。


from fastapi import FastAPI, Requestfrom fastapi.responses import JSONResponse
class UnicornException(Exception): def __init__(self, name: str): self.name = name
app = FastAPI()
@app.exception_handler(UnicornException)async def unicorn_exception_handler(request: Request, exc: UnicornException):
return JSONResponse( status_code=418, content={"message": f"Oops! {exc.name} did something. error"}, )
@app.get("/get_name_info/{name}")async def read_unicorn(name: str): if name == "haishiniu": raise UnicornException(name=name)
return {"name": name}


5


   

重写缺省异常处理器

fastapi 有一些缺省的异常处理器。当咱们抛出 HTTPException 异常或者当请求有非法数据的时候,这些处理器负责返回默认的 JSON 结果。咱们能够重写这些异常处理器。

5.1


   

重写请求校验异常处理器

当一个请求包含非法数据的时候,fastapi 内部会抛出 RequestValidationError 异常,而且有默认的异常处理器来处理。咱们能够用 @app.exception_handler(RequestValidationError) 来重写这个异常处理器。


from fastapi import FastAPI, HTTPExceptionfrom fastapi.exceptions import RequestValidationErrorfrom fastapi.responses import PlainTextResponsefrom starlette.exceptions import HTTPException as StarletteHTTPException
app = FastAPI()
@app.exception_handler(StarletteHTTPException)async def http_exception_handler(request, exc): return PlainTextResponse(str(exc.detail), status_code=exc.status_code)

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc): return PlainTextResponse(str(exc), status_code=400)

@app.get("/items/{item_id}")async def read_item(item_id: int): if item_id == 3: raise HTTPException(status_code=418, detail="Nope! I don't like 3.") return {"item_id": item_id}


5.2


   

重写 HTTPException 异常处理器

一样的方法,咱们能够重写 HTTPException 异常处理器。例如,你可能想返回纯文本格式而不是 JSON 格式的错误信息。

from fastapi import FastAPI, HTTPExceptionfrom fastapi.exceptions import RequestValidationErrorfrom fastapi.responses import PlainTextResponsefrom starlette.exceptions import HTTPException as StarletteHTTPException
app = FastAPI()
@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request, exc):
return PlainTextResponse(str(exc.detail), status_code=exc.status_code)
@app.exception_handler(RequestValidationError)async def validation_exception_handler(request, exc): return PlainTextResponse(str(exc), status_code=400)

@app.get("/items/{item_id}")async def read_item(item_id: int): if item_id == 3:
raise HTTPException(status_code=418, detail="Nope! I don't like 3.")
return {"item_id": item_id}


5.3


   

重用缺省异常处理器

咱们能够导入而且重用缺省的异常处理器。咱们从 fastapi.exception_handlers 导入缺省异常处理器。

from fastapi import FastAPI, HTTPExceptionfrom fastapi.exception_handlers import ( http_exception_handler,    request_validation_exception_handler,)
from fastapi.exceptions import RequestValidationErrorfrom starlette.exceptions import HTTPException as StarletteHTTPException
app = FastAPI()
@app.exception_handler(StarletteHTTPException)async def custom_http_exception_handler(request, exc): print(f"OMG! An HTTP error!: {repr(exc)}") return await http_exception_handler(request, exc)

@app.exception_handler(RequestValidationError)async def validation_exception_handler(request, exc): print(f"OMG! The client sent invalid data!: {exc}") return await request_validation_exception_handler(request, exc)


@app.get("/items/{item_id}")async def read_item(item_id: int): if item_id == 3: raise HTTPException(status_code=418, detail="Nope! I don't like 3.") return {"item_id": item_id}

在示例中,咱们在抛出异常以前添加了一条日志输出。咱们能够根据业务需求灵活的重用缺省异常处理器。

6


   

fastapi HTTPException 对比 Starlette HTTPException

fastapi 中 HTTPException 继承自 Starlette 的 HTTPException。
惟一的区别 fastapi 中 HTTPException 容许你在 response 添加头信息。主要在内部用于 OAuth 2.0 以及一些安全相关的功能。
所以,一般咱们在代码中抛出 fastapi 的 HTTPException 异常。可是,当咱们注册异常处理器的时候,咱们应该注册为 Starlette 的 HTTPException。这样,当 Starlette 的内部代码或者 Starlette 扩展插件抛出 Starlette HTTPException 时,咱们的处理器才能正常捕获和处理这个异常。若是咱们要在代码中同时使用这两个类,为了不命名冲突,咱们能够重命名其中一个类。

7


   

总结

1.介绍了 什么是错误以及错误的分类信息

2.在 fastapi 中是如何自定义异常处理


原创不易,只愿能帮助那些须要这些内容的同行或刚入行的小伙伴,你的每次 点赞分享 都是我继续创做下去的动力,我但愿能在推广 python 技术的道路上尽我一份力量,欢迎在评论区向我提问,我都会一一解答,记得一键三连支持一下哦!


加入python学习交流微信群,请后台回复「入群


往期推荐

python生产实战 python 闭包之庖丁解牛篇

大型fastapi项目实战 靠 python 中间件解决方案涨薪了

大型fastapi项目实战 高并发请求神器之aiohttp(下)

大型fastapi项目实战 高并发请求神器之aiohttp(上) [建议收藏]


本文分享自微信公众号 - python编程军火库(PythonCoder1024)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索