摘要:是一個(gè)和類的基于的框架,它使用了異步特性,有遠(yuǎn)超的性能。那我們能不能自定義異常處理方法呢答案當(dāng)然是可以。提供了的響應(yīng)對(duì)象。以下自定義的異常處理類無(wú)效的使用捕獲異常,返回自定義響應(yīng)數(shù)據(jù)參考鏈接最后,感謝女朋友支持。
Sanic 是一個(gè)和類Flask 的基于Python3.5+的web框架,它使用了 Python3 異步特性,有遠(yuǎn)超 flask 的性能。
編寫 RESTful API 的時(shí)候,我們會(huì)定義特定的異常錯(cuò)誤類型,比如我定義的錯(cuò)誤返回值格式為:
{ "error_code": 0, "message": "string", "text": "string" }
不同的錯(cuò)誤信息指定不同的 http 狀態(tài)碼。
sanic 提供了幾種常用的 exception:
NotFound(404)
Forbidden(403)
ServerError(500)
InvalidUsage(400)
Unauthorized(401)
RequestTimeout(408)
PayloadTooLarge(413)
這些 exception 繼承自 SanicException 類:
class SanicException(Exception): def __init__(self, message, status_code=None): super().__init__(message) if status_code is not None: self.status_code = status_code
從上述代碼可以看出,這些異常只能指定 message 和 status_code 參數(shù),那我們可不可以自定義 exception 然后在自定義的 exception 中增加參數(shù)呢?下面的代碼是按照這個(gè)思路修改后的代碼:
class ApiException(SanicException): def __init__(self, code, message=None, text=None, status_code=None): super().__init__(message) self.error_code = code self.message = message self.text = text if status_code is not None: self.status_code = status_code
使用后我得到一個(gè)結(jié)果如下:
從結(jié)果可以發(fā)現(xiàn),除了 http 狀態(tài)碼使我想要的其它全錯(cuò),連 content-type 都是 text/plain; charset=utf-8,為什么會(huì)這樣呢,我們定義的參數(shù)code 和 text 去了哪里?
翻開 sanic handler 的代碼https://github.com/channelcat/sanic/blob/master/sanic/handlers.py我找到了答案:
def default(self, request, exception): self.log(format_exc()) if issubclass(type(exception), SanicException): # 如果是 SanicException 類,返回格式是定義好的, # response 處理方法用的是 text return text( "Error: {}".format(exception), status=getattr(exception, "status_code", 500), headers=getattr(exception, "headers", dict()) ) elif self.debug: html_output = self._render_traceback_html(exception, request) response_message = ( "Exception occurred while handling uri: "{}" {}".format( request.url, format_exc())) log.error(response_message) return html(html_output, status=500) else: return html(INTERNAL_SERVER_ERROR_HTML, status=500)
從源碼可以看出,如果response 結(jié)果是 SanicException 類,response 處理方法會(huì)改用text,響應(yīng)內(nèi)容格式為 Error: status_code。
看來(lái)直接使用自定義異常類的方法不能滿足我們上邊定義的 json 格式(需要有 error_code、message 和 text)數(shù)據(jù)的要求。那我們能不能自定義 異常處理方法呢?答案當(dāng)然是可以。
下面介紹兩種自定義異常處理的方法:
使用 response.json這種方法比較簡(jiǎn)單,既然 sanic 異常處理是把錯(cuò)誤信息使用 response.text() 方法返回,那我們改成 response.json() 不就可以了么。sanic response 提供了 json 的響應(yīng)對(duì)象。可以使用 response.json 定義一個(gè)錯(cuò)誤處理方法:
def json_error(error_code, message, text, status_code): return json( { "error_code": error_code, "message": message, "text": text }, status=status_code)
這樣我們只需要在需要拋出異常的地方 return json_error(code, msg, text, status_code)。
使用這種方法有一點(diǎn)需要注意:
def get_account(): ... if account: return account else: # 如果用戶沒(méi)找到 返回錯(cuò)誤信息 return json_error(code, msg, text, status_code) @app.route("/") async def test(request): account = get_account() return text("Hello world!")
這段代碼中,如果我們沒(méi)有找到用戶信息,json_error 的返回結(jié)果會(huì)賦值給 account,并不會(huì)拋出異常,如果需要拋出異常,我們需要在 test 方法中檢查 account 的結(jié)果,如果包含 account 是 response.json 對(duì)象, 直接 return, 更正后的代碼如下:
@app.route("/") async def test(request): account = get_account() if isinstance(account, response.json): return account return text("Hello world!")
這樣雖然簡(jiǎn)單,但是會(huì)增加很多不必要的判斷,那有沒(méi)有方法可以直接拋出異常呢?這時(shí)就可以使用 sanic 提供的 @app.exception 裝飾器了。
使用 Handling exceptionssanic 提供了一個(gè) @app.exception裝飾器,使用它可以覆蓋默認(rèn)的異常處理方法。它的使用方法也很簡(jiǎn)單:
from sanic.response import text from sanic.exceptions import NotFound @app.exception(NotFound) def ignore_404s(request, exception): return text("Yep, I totally found the page: {}".format(request.url))
這個(gè)裝飾器允許我們傳入一個(gè)需要捕獲的異常的列表,然后,就可以在自定義方法中返回任意的響應(yīng)數(shù)據(jù)了。
以下自定義的異常處理類:
error_codes = { "invalid_token": ("Invalid token", "無(wú)效的token"), } def add_status_code(code): """ Decorator used for adding exceptions to _sanic_exceptions. """ def class_decorator(cls): cls.status_code = code return cls return class_decorator class MetisException(SanicException): def __init__(self, code, message=None, text=None, status_code=None): super().__init__(message) self.error_code = code _message, _text = error_codes.get(code, (None, None)) self.message = message or _message self.text = text or _text if status_code is not None: self.status_code = status_code @add_status_code(404) class NotFound(MetisException): pass @add_status_code(400) class BadRequest(MetisException): pass # 使用 app.exception 捕獲異常,返回自定義響應(yīng)數(shù)據(jù) @app.exception(Unauthorized, NotFound, BadRequest) def json_error(request, exception): return json( { "error_code": exception.error_code, "message": exception.message, "text": exception.text }, status=exception.status_code)參考鏈接
Sanic Exceptions
Metis
最后,感謝女朋友支持。
歡迎關(guān)注(April_Louisa) | 請(qǐng)我喝芬達(dá) |
---|---|
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/40690.html
摘要:快速開始在安裝之前在支持異步的過(guò)程中,都經(jīng)歷了哪些比較重大的更新。踏出第一步我們將正式使用來(lái)構(gòu)建一個(gè)項(xiàng)目,讓我們踏出第一步,利用來(lái)編寫一個(gè)返回字符串的服務(wù)程序。本次示例的源代碼全部在上,見(jiàn)。 快速開始 在安裝Sanic之前,讓我們一起來(lái)看看Python在支持異步的過(guò)程中,都經(jīng)歷了哪些比較重大的更新。 首先是Python3.4版本引入了asyncio,這讓Python有了支持異步IO的標(biāo)...
摘要:詳細(xì)信息可以看下這個(gè)問(wèn)題先在說(shuō)下我的部署方式使用部署配置文件啟動(dòng)方式總結(jié)試用了下,把之前的一個(gè)聊天機(jī)器人從改成了。預(yù)告下一篇將介紹如何使用一步一步創(chuàng)建一個(gè)聊天機(jī)器人。 簡(jiǎn)介 Sanic 是一個(gè)和類Flask 的基于Python3.5+的web框架,它編寫的代碼速度特別快。除了像Flask 以外,Sanic 還支持以異步請(qǐng)求的方式處理請(qǐng)求。這意味著你可以使用新的 async/await ...
摘要:簡(jiǎn)介是一款用寫的,用法和類似,的特點(diǎn)是非常快官網(wǎng)速度比較框架實(shí)現(xiàn)基礎(chǔ)每秒請(qǐng)求數(shù)平均時(shí)間安裝環(huán)境創(chuàng)建文件,寫入下面的內(nèi)容運(yùn)行是不是看起來(lái)和一樣屬性上傳文件列表數(shù)據(jù)數(shù)據(jù)表單數(shù)據(jù)例子路由和差不多,一看就懂注冊(cè)中間件異常處 簡(jiǎn)介 sanic是一款用python3.5+寫的web framework,用法和flask類似,sanic的特點(diǎn)是非??靏ithub官網(wǎng):https://github.c...
摘要:實(shí)例實(shí)例測(cè)試結(jié)果增加路由實(shí)例測(cè)試結(jié)果提供了一個(gè)方法,根據(jù)處理程序方法名生成。異常拋出異常要拋出異常,只需從異常模塊中提出相應(yīng)的異常。 typora-copy-images-to: ipic [TOC] 快速開始 在安裝Sanic之前,讓我們一起來(lái)看看Python在支持異步的過(guò)程中,都經(jīng)歷了哪些比較重大的更新。 首先是Python3.4版本引入了asyncio,這讓Python有了支...
摘要:在中,官方的異步協(xié)程庫(kù)正式成為標(biāo)準(zhǔn)。本項(xiàng)目就是以為基礎(chǔ)搭建的微服務(wù)框架。使用做單元測(cè)試,并且使用來(lái)避免訪問(wèn)其他微服務(wù)。跟蹤每一個(gè)請(qǐng)求,記錄請(qǐng)求所經(jīng)過(guò)的每一個(gè)微服務(wù),以鏈條的方式串聯(lián)起來(lái),對(duì)分析微服務(wù)的性能瓶頸至關(guān)重要。 介紹 使用python做web開發(fā)面臨的一個(gè)最大的問(wèn)題就是性能,在解決C10K問(wèn)題上顯的有點(diǎn)吃力。有些異步框架Tornado、Twisted、Gevent 等就是為了解...
閱讀 3633·2021-11-08 13:15
閱讀 2165·2019-08-30 14:20
閱讀 1446·2019-08-28 18:08
閱讀 1044·2019-08-28 17:51
閱讀 1552·2019-08-26 18:26
閱讀 3053·2019-08-26 13:56
閱讀 1627·2019-08-26 11:46
閱讀 2635·2019-08-23 14:22