为什么 DRF 自定义异常会引发 500 而不是 202?



exception

class CustomExcep(APIException):
def __init__(self, obj):
super(CustomExcep, self).__init__()
self.obj = obj
status_code = 202
default_detail = 'This already exists.{}'.format(self.obj)
default_code = 'accepted'

在序列化程序中

def duplicate_check(self):
if Person.objects.filter(name=name, age=age).exists():
raise CustomExcep('Person')
return True

错误:

<tr>
<th>Exception Type:</th>
<td>NameError</td>
</tr>

<tr>
<th>Exception Value:</th>
<td><pre>name &#39;self&#39; is not defined</pre></td>
</tr>

这会导致没有其他信息的通用 500 错误。 如果我删除init方法并只在不传入任何内容的情况下提高 CustomExcep,它会按预期返回 202。

我可以不将 init 用于异常类吗?

TL;大卫:你还没有叫超级__init__

当你引发一个APIException时,将调用 dunder 方法__str__。以下是 DRF 类APIException__init____str__声明:

class APIException(Exception):
"""
Base class for REST framework exceptions.
Subclasses should provide `.status_code` and `.default_detail` properties.
"""
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
default_detail = _('A server error occurred.')
default_code = 'error'
def __init__(self, detail=None, code=None):
if detail is None:
detail = self.default_detail
if code is None:
code = self.default_code
self.detail = _get_error_details(detail, code)
def __str__(self):
return six.text_type(self.detail)

如您所见,init 方法设置self.detail属性,该属性由__str__引用。您看到 500 错误的原因是您的代码中存在内部服务器错误;self.detail正在提出AttributeError.

将代码更改为:

class CustomExcep(APIException):
def __init__(self, obj):
super(CustomExcep, self).__init__()
... your code here

甚至更好;定义CustomExcep如下:

class CustomExcep(APIException):
default_code = 202
default_detail = 'Instance already exists'

其他几个问题:

  • 您传递的是字符串'Person',而不是当前实现中'Person'的对象
  • 类中__init__的签名不同于APIException类中__init__的基础签名。

第二期更新

您的代码中存在嵌入问题,它应该如下所示:

class CustomExcep(APIException):
status_code = 202
default_detail = 'This already exists.{}'.format(self.obj)
default_code = 'accepted'
def __init__(self, obj):
super(CustomExcep, self).__init__()
self.obj = obj

status_codedefault_detaildefault_code是类属性,它们需要通过缩进嵌套在类声明中。

最新更新