我正在使用django框架编写应用程序,并且正在考虑编写诸如rest控制器之类的东西,因为将异常处理逻辑放在一个地方似乎是个好主意。我不知道什么是正确的方法,但是我想出了编写一个装饰器的方法,它包含一堆可能由各种方法抛出的异常,因此,每种方法都使用该装饰器。 / p>
def exception_handler(function):
def wrapper(*args, **kwargs):
try:
return function(*args, **kwargs)
except Error1 as error:
return Response(
{"Error": str(error)},
status=status.HTTP_400_BAD_REQUEST
)
except Error2 as error:
return Response(
{"Error": str(error)},
status=status.HTTP_404_NOT_FOUND
)
except Error3 as error:
return Response(
{"Error": str(error)},
status=status.HTTP_503_SERVICE_UNAVAILABLE
)
return wrapper
Error1
,Error2
和Error3
只是一些抽象错误。在我的应用程序中,确实有更多的应用程序。
简单的控制器(又称django视图)可能看起来像这样:
class DeviceView(viewsets.ModelViewSet):
lookup_field = 'id'
serializer_class = DeviceSerializer
@exception_handler
def create(self, request):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(data=request.data)
return Response(status=status.HTTP_200_OK)
因此,基本上,如果抛出任何异常,它将以适当的方式进行处理。我在这里看到的问题之一是,如果不是我会引发带有所需消息的异常:
if some_condition:
raise SomeException("Something happened")
它将是默认值,通常我会更喜欢更改它。因此,对于控制应向客户端显示什么消息,我开始感到有些不舒服。我现在能想到的最好的方法是:
try:
this_function_throws_someexception(args)
except SomeException:
raise SomeException("Here is the message I want to show to the client")
这意味着我必须重新引发与我希望引发它的消息一起引发的异常。 我的第一个问题是“这是处理它的最好方法吗?”。第二个问题是:“异常处理的整个方法是否很好?”
答案 0 :(得分:2)
书籍和专业人士推荐的方法是进行 mixin 和双重继承。
使用 DOUBLE INHERITANCE 时,在Mixin上编写的所有内容都将重叠/覆盖并与第一个导入合并。
class A:
function gives a
no var defined
exception 1
class Bmixin:
function gives b
var is b
class X(A, Bmixin):
function gives b
exception 1
var is b (first was a but then was overriden by the Mixin because the
function is named equally)
如您所见,类X包含了两个类的所有内容,并且覆盖了两个类中定义的相似内容。
通常,您定义一个基本的ErrorHandling Mixin和一些其他特定的Mixin,并在最终视图中堆叠所需数量的Mixins。
A类(ViewStuff,ErrorBasicMixin,ErrorMoreSpecificMixin):
首先,您将所有内容放到以Mixin结尾的类上,这个名称(只是一个约定,但非常有用),包括您想要添加到类中的额外内容,在本例中为所有Exceptions。
例如
class ErrorHandlingMixing(): #No need of inheritance inside brackets "()"
#code
大多数人为mixin创建不同的.py文件,例如mixins.py
然后将其导入您的视图中
from .mixins import ErrorHandlingMixing
并在创建视图类时进行双重继承
class User (AmbstractBaseUser, PermissionsMixin):
#code
为此还创建了很多混合器,例如PermissionsMixin
from django.contrib.auth.models import PermissionsMixin
I will put you an example of a mixins.py from github
我想说装饰器方法更倾向于决定是否应处理视图,例如具有权限。我认为您可以尝试使用装饰器执行此操作,但Mixins看起来更干净,重复性更低,并且是专业人员的默认方法。
亲切的问候