
如题,之前使用的是 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": [ "该字段是必填项。" ] } } |