成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Python web 框架Sanic 學(xué)習: 自定義 Exception

2i18ns / 2555人閱讀

摘要:是一個和類的基于的框架,它使用了異步特性,有遠超的性能。那我們能不能自定義異常處理方法呢答案當然是可以。提供了的響應(yīng)對象。以下自定義的異常處理類無效的使用捕獲異常,返回自定義響應(yīng)數(shù)據(jù)參考鏈接最后,感謝女朋友支持。

Sanic 是一個和類Flask 的基于Python3.5+的web框架,它使用了 Python3 異步特性,有遠超 flask 的性能。

編寫 RESTful API 的時候,我們會定義特定的異常錯誤類型,比如我定義的錯誤返回值格式為:

{
  "error_code": 0,
  "message": "string",
  "text": "string"
}

不同的錯誤信息指定不同的 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ù)呢?下面的代碼是按照這個思路修改后的代碼:

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

使用后我得到一個結(jié)果如下:

從結(jié)果可以發(fā)現(xiàn),除了 http 狀態(tài)碼使我想要的其它全錯,連 content-type 都是 text/plain; charset=utf-8,為什么會這樣呢,我們定義的參數(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 處理方法會改用text,響應(yīng)內(nèi)容格式為 Error: status_code

看來直接使用自定義異常類的方法不能滿足我們上邊定義的 json 格式(需要有 error_code、message 和 text)數(shù)據(jù)的要求。那我們能不能自定義 異常處理方法呢?答案當然是可以。

下面介紹兩種自定義異常處理的方法:

使用 response.json

這種方法比較簡單,既然 sanic 異常處理是把錯誤信息使用 response.text() 方法返回,那我們改成 response.json() 不就可以了么。sanic response 提供了 json 的響應(yīng)對象。可以使用 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 的返回結(jié)果會賦值給 account,并不會拋出異常,如果需要拋出異常,我們需要在 test 方法中檢查 account 的結(jié)果,如果包含 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 exceptions

sanic 提供了一個 @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))

這個裝飾器允許我們傳入一個需要捕獲的異常的列表,然后,就可以在自定義方法中返回任意的響應(yīng)數(shù)據(jù)了。

以下自定義的異常處理類:

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 捕獲異常,返回自定義響應(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) 請我喝芬達

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/40690.html

相關(guān)文章

  • Sanic教程:快速開始

    摘要:快速開始在安裝之前在支持異步的過程中,都經(jīng)歷了哪些比較重大的更新。踏出第一步我們將正式使用來構(gòu)建一個項目,讓我們踏出第一步,利用來編寫一個返回字符串的服務(wù)程序。本次示例的源代碼全部在上,見。 快速開始 在安裝Sanic之前,讓我們一起來看看Python在支持異步的過程中,都經(jīng)歷了哪些比較重大的更新。 首先是Python3.4版本引入了asyncio,這讓Python有了支持異步IO的標...

    warmcheng 評論0 收藏0
  • python 最快 web 框架 Sanci 快速入門

    摘要:詳細信息可以看下這個問題先在說下我的部署方式使用部署配置文件啟動方式總結(jié)試用了下,把之前的一個聊天機器人從改成了。預(yù)告下一篇將介紹如何使用一步一步創(chuàng)建一個聊天機器人。 簡介 Sanic 是一個和類Flask 的基于Python3.5+的web框架,它編寫的代碼速度特別快。除了像Flask 以外,Sanic 還支持以異步請求的方式處理請求。這意味著你可以使用新的 async/await ...

    snifes 評論0 收藏0
  • 基于python3.5+的web框架sanic中文入門教程

    摘要:簡介是一款用寫的,用法和類似,的特點是非??旃倬W(wǎng)速度比較框架實現(xiàn)基礎(chǔ)每秒請求數(shù)平均時間安裝環(huán)境創(chuàng)建文件,寫入下面的內(nèi)容運行是不是看起來和一樣屬性上傳文件列表數(shù)據(jù)數(shù)據(jù)表單數(shù)據(jù)例子路由和差不多,一看就懂注冊中間件異常處 簡介 sanic是一款用python3.5+寫的web framework,用法和flask類似,sanic的特點是非常快github官網(wǎng):https://github.c...

    booster 評論0 收藏0
  • sanic異步框架之中文文檔

    摘要:實例實例測試結(jié)果增加路由實例測試結(jié)果提供了一個方法,根據(jù)處理程序方法名生成。異常拋出異常要拋出異常,只需從異常模塊中提出相應(yīng)的異常。 typora-copy-images-to: ipic [TOC] 快速開始 在安裝Sanic之前,讓我們一起來看看Python在支持異步的過程中,都經(jīng)歷了哪些比較重大的更新。 首先是Python3.4版本引入了asyncio,這讓Python有了支...

    elliott_hu 評論0 收藏0
  • 基于Sanic的微服務(wù)基礎(chǔ)架構(gòu)

    摘要:在中,官方的異步協(xié)程庫正式成為標準。本項目就是以為基礎(chǔ)搭建的微服務(wù)框架。使用做單元測試,并且使用來避免訪問其他微服務(wù)。跟蹤每一個請求,記錄請求所經(jīng)過的每一個微服務(wù),以鏈條的方式串聯(lián)起來,對分析微服務(wù)的性能瓶頸至關(guān)重要。 介紹 使用python做web開發(fā)面臨的一個最大的問題就是性能,在解決C10K問題上顯的有點吃力。有些異步框架Tornado、Twisted、Gevent 等就是為了解...

    seasonley 評論0 收藏0

發(fā)表評論

0條評論

2i18ns

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<