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