Python3 Как ловить цепочечные исключения - PullRequest
0 голосов
/ 27 апреля 2018

Я использую 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 эластичного поиска. Есть ли способ для меня на самом деле перехватить все исключения прежде, не меняя, как исключения генерируются в исходном коде?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...