摘要:是一個和類的基于的框架,它使用了異步特性,有遠超的性能。那我們能不能自定義異常處理方法呢答案當然是可以。提供了的響應對象。以下自定義的異常處理類無效的使用捕獲異常,返回自定義響應數據參考鏈接最后,感謝女朋友支持。
Sanic 是一個和類Flask 的基于Python3.5+的web框架,它使用了 Python3 異步特性,有遠超 flask 的性能。
編寫 RESTful API 的時候,我們會定義特定的異常錯誤類型,比如我定義的錯誤返回值格式為:
{ "error_code": 0, "message": "string", "text": "string" }
不同的錯誤信息指定不同的 http 狀態碼。
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 參數,那我們可不可以自定義 exception 然后在自定義的 exception 中增加參數呢?下面的代碼是按照這個思路修改后的代碼:
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
使用后我得到一個結果如下:
從結果可以發現,除了 http 狀態碼使我想要的其它全錯,連 content-type 都是 text/plain; charset=utf-8,為什么會這樣呢,我們定義的參數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 結果是 SanicException 類,response 處理方法會改用text,響應內容格式為 Error: status_code。
看來直接使用自定義異常類的方法不能滿足我們上邊定義的 json 格式(需要有 error_code、message 和 text)數據的要求。那我們能不能自定義 異常處理方法呢?答案當然是可以。
下面介紹兩種自定義異常處理的方法:
使用 response.json這種方法比較簡單,既然 sanic 異常處理是把錯誤信息使用 response.text() 方法返回,那我們改成 response.json() 不就可以了么。sanic response 提供了 json 的響應對象。可以使用 response.json 定義一個錯誤處理方法:
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)。
使用這種方法有一點需要注意:
def get_account(): ... if account: return account else: # 如果用戶沒找到 返回錯誤信息 return json_error(code, msg, text, status_code) @app.route("/") async def test(request): account = get_account() return text("Hello world!")
這段代碼中,如果我們沒有找到用戶信息,json_error 的返回結果會賦值給 account,并不會拋出異常,如果需要拋出異常,我們需要在 test 方法中檢查 account 的結果,如果包含 account 是 response.json 對象, 直接 return, 更正后的代碼如下:
@app.route("/") async def test(request): account = get_account() if isinstance(account, response.json): return account return text("Hello world!")
這樣雖然簡單,但是會增加很多不必要的判斷,那有沒有方法可以直接拋出異常呢?這時就可以使用 sanic 提供的 @app.exception 裝飾器了。
使用 Handling exceptionssanic 提供了一個 @app.exception裝飾器,使用它可以覆蓋默認的異常處理方法。它的使用方法也很簡單:
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))
這個裝飾器允許我們傳入一個需要捕獲的異常的列表,然后,就可以在自定義方法中返回任意的響應數據了。
以下自定義的異常處理類:
error_codes = { "invalid_token": ("Invalid token", "無效的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 捕獲異常,返回自定義響應數據 @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
最后,感謝女朋友支持。
歡迎關注(April_Louisa) | 請我喝芬達 |
---|---|
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/40690.html
摘要:快速開始在安裝之前在支持異步的過程中,都經歷了哪些比較重大的更新。踏出第一步我們將正式使用來構建一個項目,讓我們踏出第一步,利用來編寫一個返回字符串的服務程序。本次示例的源代碼全部在上,見。 快速開始 在安裝Sanic之前,讓我們一起來看看Python在支持異步的過程中,都經歷了哪些比較重大的更新。 首先是Python3.4版本引入了asyncio,這讓Python有了支持異步IO的標...
摘要:詳細信息可以看下這個問題先在說下我的部署方式使用部署配置文件啟動方式總結試用了下,把之前的一個聊天機器人從改成了。預告下一篇將介紹如何使用一步一步創建一個聊天機器人。 簡介 Sanic 是一個和類Flask 的基于Python3.5+的web框架,它編寫的代碼速度特別快。除了像Flask 以外,Sanic 還支持以異步請求的方式處理請求。這意味著你可以使用新的 async/await ...
摘要:簡介是一款用寫的,用法和類似,的特點是非常快官網速度比較框架實現基礎每秒請求數平均時間安裝環境創建文件,寫入下面的內容運行是不是看起來和一樣屬性上傳文件列表數據數據表單數據例子路由和差不多,一看就懂注冊中間件異常處 簡介 sanic是一款用python3.5+寫的web framework,用法和flask類似,sanic的特點是非常快github官網:https://github.c...
摘要:實例實例測試結果增加路由實例測試結果提供了一個方法,根據處理程序方法名生成。異常拋出異常要拋出異常,只需從異常模塊中提出相應的異常。 typora-copy-images-to: ipic [TOC] 快速開始 在安裝Sanic之前,讓我們一起來看看Python在支持異步的過程中,都經歷了哪些比較重大的更新。 首先是Python3.4版本引入了asyncio,這讓Python有了支...
摘要:在中,官方的異步協程庫正式成為標準。本項目就是以為基礎搭建的微服務框架。使用做單元測試,并且使用來避免訪問其他微服務。跟蹤每一個請求,記錄請求所經過的每一個微服務,以鏈條的方式串聯起來,對分析微服務的性能瓶頸至關重要。 介紹 使用python做web開發面臨的一個最大的問題就是性能,在解決C10K問題上顯的有點吃力。有些異步框架Tornado、Twisted、Gevent 等就是為了解...
閱讀 3553·2021-11-08 13:15
閱讀 2110·2019-08-30 14:20
閱讀 1393·2019-08-28 18:08
閱讀 983·2019-08-28 17:51
閱讀 1488·2019-08-26 18:26
閱讀 2992·2019-08-26 13:56
閱讀 1490·2019-08-26 11:46
閱讀 2590·2019-08-23 14:22