Я использую API-интерфейс Elasticsearch python для разработки удобного для пользователя приложения, которое помещает проанализированные результаты на серверasticsearch.
Проблема, с которой я столкнулся, заключается в том, что, когда я запускаю объект эластичного поиска с допустимым URL-адресом в качестве хоста, но не с действительным адресом хоста эластичного поиска, я получаю цепочечные исключения следующим образом:
Traceback (most recent call last):
File "/local/data/PYTHONLIB/lib/python3.5/site
packages/urllib3/connection.py", line 141, in _new_conn
(self.host, self.port), self.timeout, **extra_kw)
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/util/connection.py", line 83, in create_connection
raise err
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/util/connection.py", line 73, in create_connection
sock.connect(sa)
OSError: [Errno 101] Network is unreachable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/elasticsearch/connection/http_urllib3.py", line 166, in
perform_request
response = self.pool.urlopen(method, url, body, retries=False,
headers=request_headers, **kw)
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/connectionpool.py", line 639, in urlopen
_stacktrace=sys.exc_info()[2])
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/util/retry.py", line 333, in increment
raise six.reraise(type(error), error, _stacktrace)
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/packages/six.py", line 686, in reraise
raise value
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/connectionpool.py", line 601, in urlopen
chunked=chunked)
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/connectionpool.py", line 357, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/lib/python3.5/http/client.py", line 1106, in request
self._send_request(method, url, body, headers)
File "/usr/lib/python3.5/http/client.py", line 1151, in _send_request
self.endheaders(body)
File "/usr/lib/python3.5/http/client.py", line 1102, in endheaders
self._send_output(message_body)
File "/usr/lib/python3.5/http/client.py", line 934, in _send_output
self.send(msg)
File "/usr/lib/python3.5/http/client.py", line 877, in send
self.connect()
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/connection.py", line 166, in connect
conn = self._new_conn()
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/connection.py", line 150, in _new_conn
self, "Failed to establish a new connection: %s" % e)
urllib3.exceptions.NewConnectionError:
<urllib3.connection.HTTPConnection object at 0x7fc714997828>: Failed
to establish a new connection: [Errno 101] Network is unreachable
GET http://google.ca:9200/_nodes/_all/http [status:N/A
request:10.046s]
Traceback (most recent call last):
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/connection.py", line 141, in _new_conn
(self.host, self.port), self.timeout, **extra_kw)
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/util/connection.py", line 83, in
create_connection
raise err
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/util/connection.py", line 73, in create_connection
sock.connect(sa)
OSError: [Errno 101] Network is unreachable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/elasticsearch/connection/http_urllib3.py", line 166, in
perform_request
response = self.pool.urlopen(method, url, body, retries=False,
headers=request_headers, **kw)
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/connectionpool.py", line 639, in urlopen
_stacktrace=sys.exc_info()[2])
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/util/retry.py", line 333, in increment
raise six.reraise(type(error), error, _stacktrace)
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/packages/six.py", line 686, in reraise
raise value
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/connectionpool.py", line 601, in urlopen
chunked=chunked)
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/connectionpool.py", line 357, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/lib/python3.5/http/client.py", line 1106, in request
self._send_request(method, url, body, headers)
File "/usr/lib/python3.5/http/client.py", line 1151, in
_send_request
self.endheaders(body)
File "/usr/lib/python3.5/http/client.py", line 1102, in endheaders
self._send_output(message_body)
File "/usr/lib/python3.5/http/client.py", line 934, in _send_output
self.send(msg)
File "/usr/lib/python3.5/http/client.py", line 877, in send
self.connect()
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/connection.py", line 166, in connect
conn = self._new_conn()
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/urllib3/connection.py", line 150, in _new_conn
self, "Failed to establish a new connection: %s" % e)
urllib3.exceptions.NewConnectionError:
<urllib3.connection.HTTPConnection object at 0x7fc714997a20>: Failed
to establish a new connection: [Errno 101] Network is unreachable
Traceback (most recent call last):
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/elasticsearch/client/__init__.py", line 188, in __init__
self.transport = transport_class(_normalize_hosts(hosts), **kwargs)
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/elasticsearch/transport.py", line 122, in __init__
self.sniff_hosts(True)
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/elasticsearch/transport.py", line 235, in sniff_hosts
node_info = self._get_sniff_data(initial)
File "/local/data/PYTHONLIB/lib/python3.5/site-
packages/elasticsearch/transport.py", line 204, in _get_sniff_data
raise TransportError("N/A", "Unable to sniff hosts.")
elasticsearch.exceptions.TransportError: TransportError(N/A, 'Unable
to sniff hosts.')
Я хочу перехватить все исключения и создать более понятное сообщение об ошибке, например: «Недопустимый хост, ошибка подключения!»
Я попытался сделать это, не вдаваясь в подробности реализации:
from urllib3.exceptions import NewConnectionError
from elasticsearch import TransportError
try:
Elasticsearch(http,
sniff_on_start=True,
sniff_on_connection_fail=True,
sniffer_timeout=60
)
except (OSError, NewConnectionError, TransportError) as e:
print("Invalid host, connection error!")
raise SystemExit(1)
или
from urllib3.exceptions import NewConnectionError
from elasticsearch import TransportError
try:
Elasticsearch(http,
sniff_on_start=True,
sniff_on_connection_fail=True,
sniffer_timeout=60
)
except Exception as e:
print("Invalid host, connection error!")
raise SystemExit(1)
или
from urllib3.exceptions import NewConnectionError
from elasticsearch import TransportError
try:
try:
try:
Elasticsearch(http,
sniff_on_start=True,
sniff_on_connection_fail=True,
sniffer_timeout=60
)
except NewConnectionError as e:
print("Caught NewConnectionError")
except OSError as e:
print("Caught OSError")
except TransportError as e:
print("Invalid host, connection error!")
raise SystemExit(1)
Но в каждом испытании я могу поймать только TransportError, который является последним исключением, которое выдает API эластичного поиска.
Есть ли способ для меня на самом деле перехватить все исключения прежде, не меняя, как исключения генерируются в исходном коде?