0 0 0 0

Sanic is a python3 -based -based web framework with a class. Which uses asynchronous features, with, properties.

When writing a submenu api, we define a specific exception type, such as the error return format that I define:

"error_code": 0,

Different error messages specify different http status codes.

Sanic provides several common exceptions:

  • ( 404 )

  • Forbidden ( 403 )

  • ServerError ( 500 )

  • Invalidusage ( 400 )

  • Unauthorized ( 401 )

  • RequestTimeout ( 408 )

  • Payloadtoolarge ( 413 )

These exceptions inherit from the sanicexception class:

class SanicException(Exception):
 def __init__(self, message, status_code=None):
 if status_code is not None:
 self.status_code = status_code

As you can see from the above code, these exceptions can only specify the message and status_code parameters, so we can customize the exception and then add the The following code is modified according to this idea:

class ApiException(SanicException):
 def __init__(self, code, message=None, text=None, status_code=None):
 self.error_code = code
 self.message = message
 self.text = text
 if status_code is not None:
 self.status_code = status_code

After use I get a result as follows:

From the results you can find that other than the http state, the other I want, even content-type is text/plain; charset=utf-8, why would we've defined the parameter code and the

Open the code for sanic, and I found the answer:

def default(self, request, exception):
 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:"{}"n{}'.format(
 request.url, format_exc()))
 return html(html_output, status=500)
 return html(INTERNAL_SERVER_ERROR_HTML, status=500)

As you can see from the source code, if the response is a sanicexception class, the response processing method uses text instead of Error: status_code.

It appears that methods that use custom exception classes directly cannot satisfy the json format defined above ( requiring error_code, message, and text ) data. Can we customize the exception handling method. .

The following two methods for custom exception handling are described:

Using response. Json.

This method is simple, since the sanic exception handling is to use the response, text ( ) method back to the response. The sanic response provides the respo & e object for the json. You can define a error handling method by using response.json:

def json_error(error_code, message, text, status_code):
 return json(
 'error_code': error_code,
 'message': message,
 'text': text

So we just need to throw an exception where we need to throw an exception. return json_error(code, msg, text, status_code) .

There's a point in using this method:

def get_account():
. . .
 if account:
 return account
 # 如果用户没找到 返回错误信息
 return json_error(code, msg, text, status_code)
async def test(request):
 account = get_account()
 return text('Hello world!')

In this code, if we don't find the user information, the return result of the json_error is assigned to account, and no exception is thrown. If an exception is thrown, the.

async def test(request):
 account = get_account()
 if isinstance(account, response.json):
 return account
 return text('Hello world!')

This is simple, but will add a lot of unnecessary judgment, and there's no way to throw an exception directly. You can then use the @app.exception adorner provided by sanic.

Use handling width

Sanic provides a @app.exception adorner that can override the default exception handling method. It's also simple to use:

from sanic.response import text
from sanic.exceptions import NotFound
def ignore_404s(request, exception):
 return text("Yep, I totally found the page: {}".format(request.url))

This adorner allows us to pass in a list of exceptions that need to be captured, and then we can return to any response data in the custom method.

The following custom exception handling classes:

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):
 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
class NotFound(MetisException):
class BadRequest(MetisException):
# 使用 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

Reference link

Finally, thank you for your.

Welcome to focus ( april_louisa ), please.

Copyright © 2011 Dowemo All rights reserved.    Creative Commons   AboutUs