代码之家  ›  专栏  ›  技术社区  ›  Richard Levasseur

将业务层错误与API错误分开

  •  1
  • Richard Levasseur  · 技术社区  · 16 年前

    我知道这个标题很糟糕;我在这里的标题很糟糕。

    我想知道当错误可能在应用程序内部深层次出现时,在WebAPI中呈现统一错误响应的最佳方法是什么。

    应用程序中深层的错误对网络层一无所知(也不应该知道),所以网络层如何分类 myapp.PermissionError 进入403, json.DecodeError 变成400人, myapp.driver.InvalidValue 到500等。

    我有一些想法,但我不是他们中的任何一个的大粉丝。

    (正如代码片段可能暗示的那样,这是Linux上的一个python应用程序)

    1. 大量使用 except 块以匹配所需的异常类型。这正是我目前正在做的,但它越来越笨拙(我已经8岁了,还有很多事情要做)。

      try
        business.DoIt()
      except DecodingError:
        respond(400)
      except PermissionError:
        response(403)
      ...etc...
      
    2. 创建异常类型的映射或列表,并将其映射到响应代码。最后,这似乎并不比(1)好多少,但它确实清理了代码。

      error_map = [(DecodingError, 400), (PermissionError, 403)]
      try:
        DoIt()
      except Exception, exc:
        for type, code in error_map:
          if isinstance(exc, type):
             response(code)
             return
      
    3. 为每个提供响应代码的异常类添加一个接口,但我不喜欢这样,因为异常包含了特定于Web层的信息(即使它们深入到根本不关心Web层的驱动程序中)。不过,我确实喜欢Web错误响应的“自动性”。

      class PermissionError(Exception):
        web_status_code = 403
      try:
        Doit()
      except:
        response(exc.web_status_code)
      
    1 回复  |  直到 16 年前
        1
  •  1
  •   Josh Wright    16 年前

    我喜欢选项1。它可能有点冗长,但也很清楚。

    选项2将引发异常的点与做出如何处理异常的决定的点分开。事实上,这可能不会是一个太多的问题,但是如果你不必这么做,为什么要把它分开呢?

    我同意选项3相当难看。不需要处理该级别的错误行为,只需抛出异常即可。