Requests: 如果状态代码不等于 200,则引发异常

创建于 2014-07-27  ·  3评论  ·  资料来源: psf/requests

你好,
我经常期望请求的状态代码为 200,如果没有,我无能为力(严重的是,当服务器返回错误 500 时,我将无法执行某些操作)。 所以我需要写这样的代码:

    r = requests.get(self.url(False))
    if r.status_code != 200:
        raise requests.ConnectionError("Expected status code 200, but got {}".format(page.status_code))

我认为名为 allowed_status_codes 的 kwarg 会非常方便。 它可以这样实现:
默认情况下它是NoneNone ,空列表或元组表示允许所有状态代码。 它可以是整数、列表、元组或枚举。 如果是整数,则只允许此特定状态代码。 如果它是列表或元组,则只允许列表/元组内的状态代码。 该列表可能具有整数和/或枚举。 枚举应该更灵活一点。
例如,如果我想允许所有“成功”(2xx) 请求,我可以写:allowed_status_codes=requests.ALLOW_SUCCESS,除非状态代码是 2xx,否则它将抛出异常。 如果我只想禁止服务器错误(从而处理未验证的错误),我可以简单地编写 allowed_status_codes=requests.DISALLOW_SERVER_ERROR,如果服务器代码为 5xx,它将引发异常。
当然,应该有很多涵盖特定情况的枚举。 并且还应该能够在列表中组合使用它(例如(200, ALLOW_REDIRECTIONS) )。
如果不允许使用状态代码,则会引发StatusCodeError(RequestException)


尽管我提到了枚举,但我并不是在谈论 Python 3.4 的枚举值。 我说的是常量。 枚举(常量)可以这样实现:

#request model.

ALLOW_SUCCESS = AllowSuccessEnum()
# other enums

class RequestEnum(object):
     def is_status_code_allowed(status_code):
         raise NotImplementedError

class AllowSuccessEnum(RequestEnum):
    def is_status_code_allowed(status_code):
        # return false unless status code is 2xx

最有用的评论

另外,如果状态代码不是 200,每个Response是否都有一个raise_for_status方法会引发异常?

Python 2.7.7 (default, Jun  2 2014, 18:55:26)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> r = requests.get('http://httpbin.org/404')
>>> r
<Response [404]>
>>> r.raise_for_status()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/requests/models.py", line 795, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: NOT FOUND

所有3条评论

谢谢你的想法!

目前尚不清楚为什么这属于请求本身。 所需的代码并不复杂,我不相信通过将这些代码放在库中会增加多少价值。 然而,我们_会_向 API 添加另一个关键字参数,这是我们大部分时间不愿意做的事情。

另外,如果状态代码不是 200,每个Response是否都有一个raise_for_status方法会引发异常?

Python 2.7.7 (default, Jun  2 2014, 18:55:26)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> r = requests.get('http://httpbin.org/404')
>>> r
<Response [404]>
>>> r.raise_for_status()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/requests/models.py", line 795, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: NOT FOUND

@Lukasa因为它非常方便,可以节省大量代码(假设一个项目使用请求。这个项目使用了大约 100 次请求。所以,它_可以_节省 200 行代码,并防止打字错误,因为我将不得不写异常 100 次(如果我不使用引发异常的方法),并且它统一了异常/错误(另一个 API 可能会使用请求并在状态代码无效的情况下引发自定义错误。我更喜欢它,如果它抛出与请求相同的异常)。

@sigmavirus24抱歉,我不知道这种方法存在。 您应该提到 HTTPError 可以通过 raise_for_status 在文档的 Error and Exceptions 部分引发。 HTTPError 目前声称仅在“在无效 HTTP 响应的罕见事件中”引发。
您还可以考虑将我的一些想法实现到我的 raise_for_status 中,以便它也可以允许其他状态代码。

此页面是否有帮助?
0 / 5 - 0 等级