在Python中处理自定义异常的正确方法是什么



根据我所读的内容,EAFP(比权限更容易请求原谅(是Python中公认的编码风格,实际上在许多情况下都是推荐的。

我的问题是,对于自定义例外,什么时候会变得太多。想象一下,我们有一个狗旅馆的网络应用程序,其结构如下:

- controllers
-- dogs.py (Receives REST requests)
- services
-- dogs.py (Connects to a DB and a third party API to retrieve dog breed information)
-- validator.py

现在有三个请求示例:

  1. 有人想创建一只新狗,但提供了无效信息。因此,验证器有一个返回False的is_valid_dog方法
  2. 有人发出GET请求来检索某只不存在的狗的信息。狗狗服务访问了数据库,但一无所获
  3. 用户想要狗的品种信息,服务访问第三方API,但它关闭了(获得500状态(

处理这种类型的流的最佳方法是什么?

  1. 在第一种情况下,当is_valid_dog返回False时,我应该引发异常吗?或者向控制器返回None/False,以便将其映射到400状态代码
  2. 我是否应该返回None,以便控制器将返回值映射到404
  3. 我是否应该捕获异常并用消息引发自定义ThirdPartyAPIException,并且控制器必须知道如何处理它

我很好奇什么时候返回特定的值,或者只是在不同的层之间引发异常,这样控制器就可以返回最终状态。一般来说,哪里是处理这些异常/流的最佳位置。

您应该遵循DRF的方法,它是RESTful django api的事实标准。看看DRF的源代码:https://github.com/encode/django-rest-framework/blob/master/rest_framework/exceptions.py.

  1. 创建一个默认的ValidationError异常,根据上下文自定义每个错误。如果引发异常,则返回400状态代码;

  2. 如果返回None,则引发NotFound异常,状态码为404

  3. 我会坚持捕获异常并显示503代码"Service Unavailable"。

查看类APIException,了解异常流和这些错误的响应。

对于第一个请求示例:

  • 我会将valid_dog中的错误返回给控制器,以便在响应中显示它,这将引发一个400坏请求状态代码

对于第二个请求示例:

  • 我将向控制器返回空查询,这将引发404未找到状态代码

对于第三个请求示例:

  • 我将通过引发424 FAILED DEPENDENCY状态代码或503 SERVICE UNAVAILABLE来处理控制器中的异常,并给出解释问题的响应

例如,为django-rest框架设置自定义异常:

from django.utils.encoding import force_text
from rest_framework.exceptions import APIException
class ServiceUnavailable(APIException):
"""
Raise error for external services that cannot be reached
"""
status_code = 503
default_detail = "Service temporarily unavailable, try again later."
default_code = "service_unavailable"
def __init__(self, detail, field):
if detail is not None:
self.detail = {field: [force_text(detail)]}
else:
self.detail = {"detail": force_text(self.default_detail)}

相关内容

最新更新