Flask中异常的统一管理

异常统一管理

自定义异常

Flask默认的返回的异常是html格式的页面,但是为了更好地支持json相关信息的返回,我们需要重写异常类的返回。在Flask中,异常类统一继承了werkzeug.exceptions中的HTTPException异常类,因此我们也需要重写一个类来继承它。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from flask import request, json
from werkzeug.exceptions import HTTPException


class APIException(HTTPException):
code = 500
description = 'one unknown exception happened in backend.'
error_code = 999

def __init__(self, description=None, code=None, error_code=None):
if code:
self.code = code
if error_code:
self.error_code = error_code
if description:
self.description = description
super(APIException, self).__init__(description, None)

def get_body(self, environ=None, scope=None):
body = dict(
description=self.description,
error_code=self.error_code,
request=request.method + ' ' + self.get_url_no_param()
)
text = json.dumps(body)
return text

def get_headers(self, environ=None, scope=None):
return [('Content-Type', 'application/json')]

@staticmethod
def get_url_no_param():
full_path = str(request.full_path)
main_path = full_path.split('?')
return main_path[0]

这里我们完成了一个APIException类,其中主要重写了get_headers以及get_body,默认的headers是html,body是对应的网页内容,而我们的需求是headers是支持json,body是对应的json内容。同时在这个类中我们引入了code以及error_code,其中error_code是我们自定义的标识。完成自定义内容的保存之后,将其中的description传递给父类。

APIException是接下来我们所有自定义异常的统一父类,我们可以实现各个具体的异常类,如下所示,只需要更新其中的属性即可:

1
2
3
4
class NoSuchIDException(APIException):
code = 400
description = 'no such id'
error_code = 100

引入了对应的异常,则可以在对应的地方进行raise,按照正常的使用逻辑即可。

异常处理

完成了自定义异常的定义之后,我们需要向整个系统进行异常处理的注册,用于全局的异常捕获。这个方法需要在app初始化之后执行:

1
2
3
4
5
6
7
8
# handle all exception
@app.errorhandler(Exception)
def framework_exception(exception):
logging.exception(exception)
if isinstance(exception, HTTPException):
return exception
else:
return APIException()

这个方法将异常分为两个部分,一个是HTTPException,其中就包括我们自定义的异常,对于这部分异常我们可以直接返回。另一个是非HTTPException,对于这类异常,我们将其包装成统一的一个默认异常,使用的是我们在APIException中的默认实现。同时为了后端异常的定位,这里可以使用logging.exception来打印异常的堆栈信息。

参考文章

  1. Handling Application Errors — Flask Documentation (2.0.x) (palletsprojects.com)
  2. flask 重写HTTPException类并自定义异常信息 - 吹神 - 博客园 (cnblogs.com)

Flask中异常的统一管理
http://example.com/2023/03/25/Flask中异常的统一管理/
作者
EverNorif
发布于
2023年3月25日
许可协议