Mad*_*vad 5 python error-handling python-3.x python-requests
我一直使用:
r = requests.get(url)
if r.status_code == 200:
# my passing code
else:
# anything else, if this even exists
Run Code Online (Sandbox Code Playgroud)
现在我正在处理另一个问题并决定允许其他错误,而是现在使用:
try:
r = requests.get(url)
r.raise_for_status()
except requests.exceptions.ConnectionError as err:
# eg, no internet
raise SystemExit(err)
except requests.exceptions.HTTPError as err:
# eg, url, server and other errors
raise SystemExit(err)
# the rest of my code is going here
Run Code Online (Sandbox Code Playgroud)
除了可以在此级别测试各种其他错误之外,一种方法是否比另一种方法更好?
Sam*_*gan 73
Response.raise_for_status()只是一个用于检查状态代码的内置方法,其作用与第一个示例基本相同。
这里没有“更好”,只是关于流量控制的个人喜好。我更喜欢使用 try/ except 块来捕获任何调用中的错误,因为这会通知未来的程序员这些条件是某种错误。if/else 不一定表示扫描代码时出现错误。
编辑:这是我的快速而肮脏的模式。
import time
from http import HTTPStatus
import requests
from requests.exceptions import HTTPError
url = "https://theurl.com"
retries = 3
retry_codes = [
HTTPStatus.TOO_MANY_REQUESTS,
HTTPStatus.INTERNAL_SERVER_ERROR,
HTTPStatus.BAD_GATEWAY,
HTTPStatus.SERVICE_UNAVAILABLE,
HTTPStatus.GATEWAY_TIMEOUT,
]
for n in range(retries):
try:
response = requests.get(url)
response.raise_for_status()
break
except HTTPError as exc:
code = exc.response.status_code
if code in retry_codes:
# retry after n seconds
time.sleep(n)
continue
raise
Run Code Online (Sandbox Code Playgroud)
然而,在大多数情况下,我会子类化requests.Session,创建一个HTTPAdapter处理指数退避的自定义,并且上面的内容存在于重写的requests.Session.request方法中。可以在这里看到一个例子。
Ian*_*dby 30
几乎总是raise_for_status()更好。
主要原因是它比测试更多一些status_code == 200,您应该充分利用经过尝试和测试的代码,而不是创建自己的实现。
例如,您是否知道 HTTP 标准实际上定义了五种不同的“成功”代码?通过测试,其中四个“成功”代码将被误解为失败status_code == 200。
Gre*_*cki 17
如果您不确定,请遵循Ian Goldby 的回答。
...但是请注意,这raise_for_status()并不是什么神奇或异常智能的解决方案 - 它是一个非常简单的函数,用于解码响应正文并抛出 HTTP 代码 400-599 的异常,区分客户端和服务器端错误(请参阅其代码在这里)。
特别是客户端错误响应可能在您可能想要处理的响应正文中包含有价值的信息。例如,HTTP 400 Bad Request 响应可能包含错误原因。
在这种情况下,最好不要使用raise_for_status(),而是自己覆盖所有情况。
try:
r = requests.get(url)
# process the specific codes from the range 400-599
# that you are interested in first
if r.status_code == 400:
invalid_request_reason = r.text
print(f"Your request has failed because: {invalid_request_reason}")
return
# this will handle all other errors
elif r.status_code > 400:
print(f"Your request has failed with status code: {r.status_code}")
return
except requests.exceptions.ConnectionError as err:
# eg, no internet
raise SystemExit(err)
# the rest of my code is going here
Run Code Online (Sandbox Code Playgroud)
PuppetDB 的 API 使用Puppet 查询语言 (PQL),以 HTTP 400 错误请求响应语法无效的查询,并提供非常精确的错误信息。
请求查询:
nodes[certname] { certname == "bastion" }
Run Code Online (Sandbox Code Playgroud)
HTTP 400 响应的正文:
PQL parse error at line 1, column 29:
nodes[certname] { certname == "bastion" }
^
Expected one of:
[
false
true
#"[0-9]+"
-
'
"
#"\s+"
Run Code Online (Sandbox Code Playgroud)
请参阅我对使用此 API 的应用程序的 Pull 请求,以使其向用户显示此错误消息,但请注意,它并不完全遵循上面的示例代码。
| 归档时间: |
|
| 查看次数: |
2110 次 |
| 最近记录: |