当前位置: 首页 > 面试题库 >

Django-异常处理最佳实践并发送自定义错误消息

隗轶
2023-03-14
问题内容

我开始考虑在我的Django应用程序中进行适当的异常处理,并且我的目标是使它尽可能地易于使用。出于用户友好的目的,我暗示用户必须始终就确切的错误之处获得详细的说明。

使用状态为200的JSON响应进行常规响应,并返回(适当的!)4xx /
5xx响应以获取错误。它们也可以携带JSON有效负载,因此您的服务器端可以添加有关错误的其他详细信息。

我试图用这个答案中的关键词来搜索谷歌,但我的脑海中仍然有比答案更多的问题。

  1. 如何确定返回哪个错误代码-400或500?我的意思是,Django有许多预定义的错误类型,如何在Django异常类型和400-500错误代码之间实现这种映射,以使异常处理块尽可能地干燥并可重用?
  2. @Reorx在帖子中建议的使用中间件的方法是否被认为可行?(答案只有一次投票,因此我不愿深入研究细节并在我的项目中实施
  3. 最重要的是,有时我可能希望引发与业务逻辑相关的错误,而不是语法错误或诸如空值之类的标准错误。例如,如果我的法人实体中没有CEO,我可能想禁止用户添加合同。在这种情况下,错误状态应该是什么?如何为用户提供详细的错误解释以抛出错误?

让我们从简单的角度考虑它

def test_view (request):

   try:
          # Some code .... 
          if my_business_logic_is_violated():
              # How do I raise the error
              error_msg = "You violated bussiness logic because..."
              # How do I pass error_msg 
          my_response = {'my_field' : value}
  except ExpectedError as e:
          # what is the most appropriate way to pass both error status and custom message
          # How do I list all possible error types here (instead of ExpectedError to make the exception handling block as DRY and reusable as possible
      return JsonResponse({'status':'false','message':message}, status=500)

问题答案:

首先,您应该考虑要暴露哪些错误:

  • 通常会披露4xx错误(归因于客户端的错误),以便用户可以更正请求。

  • 另一方面,通常仅在没有信息的情况下显示5xx错误(归因于服务器端的错误)。在我看来,对于那些您应该使用诸如Sentry之类的工具来监视和解决此错误,这些错误中可能嵌入了安全性问题。

在我看来,考虑到正确的Ajax请求,您应该返回一个状态码,然后返回一些json以帮助理解发生了什么,例如消息和解释(适用时)。

如果您的目标是使用Ajax提交信息,建议您为所需内容设置一个表格。这样,您就可以轻松地通过一些验证过程。我将在示例中假设情况是这样。

首先 -请求正确吗?

def test_view(request):
    message = None
    explanation = None
    status_code = 500
    # First, is the request correct?
    if request.is_ajax() and request.method == "POST":
        ....
    else: 
        status_code = 400
        message = "The request is not valid."
        # You should log this error because this usually means your front end has a bug.
        # do you whant to explain anything?
        explanation = "The server could not accept your request because it was not valid. Please try again and if the error keeps happening get in contact with us."

    return JsonResponse({'message':message,'explanation':explanation}, status=status_code)

第二 -表格中是否有错误?

form = TestForm(request.POST)
if form.is_valid():
    ...
else:
    message = "The form has errors"
    explanation = form.errors.as_data()
    # Also incorrect request but this time the only flag for you should be that maybe JavaScript validation can be used.
    status_code = 400

您甚至可能逐字段获取错误,因此可以在表单本身中以更好的方式呈现。

第三 -让我们处理请求

        try:
            test_method(form.cleaned_data)
        except `PermissionError` as e:
            status_code= 403
            message= "Your account doesn't have permissions to go so far!"
        except `Conflict` as e:
            status_code= 409
            message= "Other user is working in the same information, he got there first"
        ....
        else:
            status_code= 201
            message= "Object created with success!"

根据您定义的例外,可能需要不同的代码。转到Wikipedia并检查列表。不要忘记,响应的代码也不同。如果您向数据库中添加内容,则应返回201。如果您只是获得信息,那么您正在寻找GET请求。

回答问题

  1. 如果不处理,Django异常将返回500个错误,因为如果您不知道会发生异常,那么这是服务器中的错误。除了404和登录要求外,我将对try catch所有内容进行阻止。(对于404,您可以将其提高,如果您这样做@login_required或获得所需权限,django会在不执行任何操作的情况下以适当的代码进行响应)。

  2. 我不同意这种方法。正如您所说,错误应该是明确的,因此您应该始终知道将要发生的情况以及如何进行解释,并使其取决于所执行的操作。

  3. 我会说400错误是可以的。您只是需要解释原因,这是一个错误的请求,错误代码适合您和您的js代码,因此请保持一致。

  4. (提供示例)-在第三个示例中,text_view您应具有test_method

测试方法应具有以下结构:

def test_method(validated_data):
    try: 
        my_business_logic_is_violated():
    catch BusinessLogicViolation:
        raise
    else:
        ... #your code

在我的示例中:

   try:
        test_method(form.cleaned_data)
    except `BusinessLogicViolation` as e:
        status_code= 400
        message= "You violated the business logic"
        explanation = e.explanation
   ...

我认为违反业务逻辑是“客户端错误”,因为如果在该请求之前需要进行某些操作,则客户端应该意识到这一点,并要求用户先执行此操作。(来自错误定义):

400(错误请求)状态码表示服务器由于某些原因(例如格式错误的请求语法,无效的请求
消息框架或欺骗性的请求路由)而被视为客户端错误,因此服务器无法处理该请求。

顺便说一句,您可以查看有关用户html" target="_blank">定义的异常的Python文档,因此您可以提供适当的错误消息。该示例背后的想法是,您会根据生成BusinessLogicViolation消息my_business_logic_is_violated()的位置引发异常,并带有不同的消息。



 类似资料:
  • 问题内容: 如果我的应用程序崩溃了,它会挂起几秒钟,然后Android告诉我该应用程序崩溃了,需要关闭。所以我当时想用通用的方式捕获应用程序中的所有异常: 并做一个新的解释,说明应用程序立即崩溃(并且还使用户有机会发送包含错误详细信息的邮件),而不是由于Android而造成了延迟。是否有更好的方法来实现这一目标? 更新: 我使用的是启用了ART的Nexus 5,但我没有注意到我以前遇到的崩溃(我最

  • 问题内容: 几天前我才开始尝试使用node.js。我意识到只要程序中有未处理的异常,Node就会终止。这与我所见过的普通服务器容器不同,在普通服务器容器中,当发生未处理的异常时,只有工作线程死亡,并且容器仍然能够接收请求。这引起了一些问题: 是唯一有效的预防方法吗? 在执行异步过程期间也会捕获未处理的异常吗? 是否存在已经构建的模块(例如发送电子邮件或写入文件),在未捕获的异常的情况下可以利用该模

  • 并创建一个新的,解释应用程序立即崩溃(并给用户发送包含错误详细信息的邮件的机会),而不是由于Android造成的延迟。有没有更好的方法来实现这一点,或者这是不鼓励的? 更新:我使用的Nexus 5启用了ART功能,我没有注意到应用程序崩溃时的延迟(我最初说的“挂起”)。我想既然现在一切都是本机代码,崩溃就会立即发生,同时得到所有的崩溃信息。也许Nexus5只是速度很快:)不管怎样,这在未来的And

  • 现在我打算创建一个更好的错误处理的“应用程序”框架,我试图寻找最佳实践,但没有找到任何 泽西文档:https://Jersey.java.net/nonav/documentation/1.9/user-guide.html#D4E443 Internet上的几个搜索:http://www.codingpedia.org/ama/error-handing-in-rest-api-with-jer

  • 本文向大家介绍详解Spring MVC/Boot 统一异常处理最佳实践,包括了详解Spring MVC/Boot 统一异常处理最佳实践的使用技巧和注意事项,需要的朋友参考一下 前言 在 Web 开发中, 我们经常会需要处理各种异常, 这是一件棘手的事情, 对于很多人来说, 可能对异常处理有以下几个问题: 什么时候需要捕获(try-catch)异常, 什么时候需要抛出(throws)异常到上层. 在

  • 我为运行时可能发生的各种错误创建了多个自定义异常。为此,我使用@ControllerAdvice注释和全局错误处理程序(如下所述:Spring Boot 异常处理。我还在数据库级别实现了约束(如果这很重要,它是一个SQL Server数据库),并且我有一个表,该表具有插入数据时可能引发的两个不同约束。 我现在想做的是在Spring Boot中为数据库级别的每个约束实现自定义异常,这样我就可以向用户