如题,之前使用的是 flask 框架, 抛出的异常都是自定义状态码和详细的异常信息, 抛出异常的格式为:
{
"code": "1001",
"data": {},
"response": "请求不符合规范",
"time": 2
}
然后现在学习使用 drf 框架, 比如在序列化器校验的时候抛出一个异常:
raise serializers.ValidationError('登录密码错误')
这个时候通过 postman 去故意触发这个报错,返回信息如下:
{
"non_field_errors": [
"登录密码错误"
]
}
然后我在序列化器中定义一个方法def validate_username
去检验用户名称,在该方法中定义一个异常:
raise serializers.ValidationError('用户名称不符合规范')
然后故意去触发该异常,返回的信息如下:
{
"username": [
"用户名称不符合规范"
],
}
我现在就有点蒙了, 为什么返回异常的字段还会不断的变化?或者我应该怎么样捕获到它所有的异常来统一处理呢?网上有人说定义方法重新捕获,但是像如上的这种情况,连异常的字段信息都不一致,我该如何捕捉到具体的报错信息呢?
1
lynskylate 2020-01-09 09:48:38 +08:00 via Android
你定义的 validate username 检查的是定义的 model 中 username 这个 field,drf 对于每个 field 都会检查,抛出的错误中 key 是检查失败的 field 名。
|
2
Jammar 2020-01-09 09:53:25 +08:00
抛出异常上层捕获异常
|
3
kayseen OP @lynskylate
是的, 我在定义的`def validate`方法中抛出的异常字段名为`non_field_errors`, 请教一下关于 drf 的异常你是怎么处理的? |
4
kayseen OP @Jammar
你好, 这个思想我知道,我在上层捕获到的异常具体为: ```python {'non_field_errors': [ErrorDetail(string='登录密码错误', code='invalid')]} ``` 然后就获取不到 string 的具体信息了...... |
5
lynskylate 2020-01-09 10:00:13 +08:00 via Android
@kayseen drf 可以定义统一处理异常的函数,也有定义处理响应的地方。
|
6
hccsoul 2020-01-09 10:52:12 +08:00
第一瞬间看成 dnf,臭打游戏的没救了--
|
7
Hstar 2020-01-09 10:59:31 +08:00
建议你手动写一个 view,直接 raise Exception 的那种。
你所说的字段变化是 ValidationError 的特性,分别理解比较容易。 |
8
stephenyin 2020-01-09 12:10:10 +08:00
看见中出就进来了
|
9
Rand01ph 2020-01-09 13:27:02 +08:00
我这边都是直接在业务逻辑 raise 自定义异常,然后定义自定义异常处理函数,根据不同的异常生成返回.
|
10
Jammar 2020-01-09 15:51:56 +08:00
设置里面 drf 的设置配置这个字段'EXCEPTION_HANDLER'
|
11
lgh 2020-01-10 00:04:48 +08:00
|
12
kayseen OP |
13
kayseen OP @Rand01ph
你好,我想问的好像就是你说的这个,请问你是不是在下面的这个函数中定义的处理? ```python from rest_framework.views import exception_handler def custom_exception_handler(exc, context): # Call REST framework's default exception handler first, # to get the standard error response. response = exception_handler(exc, context) # Now add the HTTP status code to the response. if response is not None: response.data['status_code'] = response.status_code return response ``` |
15
leinal 2020-02-17 16:37:56 +08:00
想问下楼主,这个问题搞定了吗?目前也是这个问题。
|
16
kayseen OP 没有(>﹏<) 你搞定的话麻烦说下
|
18
sxy960806 2020-02-27 22:44:18 +08:00
def custom_exception_handler(exc, context):
response = exception_handler(exc, context) if response: detail = response.data.get('detail') non_field_errors = response.data.get('non_field_errors') # 异常响应 if detail: return Response({'response': detail, 'data': {}, 'code': '1001'}) elif non_field_errors: return Response({'response': non_field_errors[0], 'data': {}, 'code': '1001'}) else: return Response({'response': '接口参数错误', 'data': {}, 'code': '1001', 'tips': response.data}) return response 可以按照我这个思路来添加异常处理 效果如下: # 登陆失败 { "response": "无法使用提供的认证信息登录。", "data": {}, "code": "1001" } # 开发阶段字段不完整或字段校验错误 { "response": "接口参数错误", "data": {}, "code": "1001", "tips": { "end_date": [ "该字段是必填项。" ], "priority": [ "该字段是必填项。" ], "auditor": [ "该字段是必填项。" ] } } |