简体   繁体   English

python 请求/urllib3 连接池没有捕获 HTTP 错误

[英]python requests/urllib3 connection pooling not catching HTTP errors

python requests (urllib3) with connection pooling is not catching http errors.带有连接池的 python 请求 (urllib3) 没有捕获 http 错误。 Is this a bug?这是一个错误吗? Or am I doing something wrong?还是我做错了什么?

#!/usr/bin/env python

import contextlib
import requests
import sys

connection_pool_size = 2
adapter = requests.adapters.HTTPAdapter(pool_connections=connection_pool_size,
                                        pool_maxsize=connection_pool_size)
r_session = requests.Session()
r_session.mount('http', adapter)

try:
    with contextlib.closing(r_session.get(sys.argv[1], timeout=30, allow_redirects=True)) as r:
        print 'success %r' % r
except requests.exceptions.HTTPError as e:
    print 'HTTPError %r' % e
except Exception as e:
    print 'Exception %r' % e

output:输出:

$ ./test.py https://github.com
success <Response [200]>
$ ./test.py https://github.com/sithlordyoyoma
success <Response [404]>

I was expecting HTTPError .我期待 HTTPError 。 Am I doing something wrong?难道我做错了什么?

Closing with contextlib I got from this thread should I call close() after urllib.urlopen()?关闭我从这个线程得到的 contextlib 我应该在 urllib.urlopen() 之后调用 close() 吗? . . As suggested by Alex Martelli.正如亚历克斯·马泰利所建议的那样。

actually running requests without connection also showing this behaviour实际上在没有连接的情况下运行请求也显示了这种行为

#!/usr/bin/env python

import contextlib
import requests
import sys


try:
    with contextlib.closing(requests.get(sys.argv[1], timeout=30, allow_redirects=True)) as r:
        print 'success %r' % r
except requests.exceptions.HTTPError as e:
    print 'HTTPError %r' % e
except Exception as e:
    print 'Exception %r' % e

output:输出:

$ ./test.py https://github.com
success <Response [200]>
$ ./test.py https://github.com/sithlordyoyoma
success <Response [404]>

urllib2 does this correctly urllib2 正确执行此操作

#!/usr/bin/env python

import contextlib
import urllib2
import sys


try:
    with contextlib.closing(urllib2.urlopen(sys.argv[1], timeout=30)) as r:
        print 'success %r' % r
except urllib2.HTTPError as e:
    print 'HTTPError %r' % e
except Exception as e:
    print 'Exception %r' % e

output:输出:

$ ./test.py https://github.com
success <addinfourl at 4338734792 whose fp = <socket._fileobject object at 0x1025a5c50>>
$ ./test.py https://github.com/sithlordyoyoma
HTTPError HTTPError()

Regardless of connection pooling, requests.post (and other HTTP methods) does not raise HTTPError on a 404. HTTPError is raised by calling .raise_for_status() , like this example demonstrates:无论连接池如何, requests.post (和其他 HTTP 方法)都不会在 404 上引发HTTPError 。通过调用.raise_for_status()引发HTTPError ,如下例所示:

#!/usr/bin/env python

import requests

r = requests.post(
    'https://github.com/sithlordyoyoma',
    timeout=30,
    allow_redirects=True
)
print 'success %r' % r
r.raise_for_status()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM