Устойчивость к ошибкам сокетов Python / обходной путь - PullRequest
2 голосов
/ 31 октября 2011

У меня запущен скрипт, который проверяет серию URL-адресов на доступность.

Это одна из функций.

def checkUrl(url): # Only downloads headers, returns status code.
    p = urlparse(url)
    conn = httplib.HTTPConnection(p.netloc)
    conn.request('HEAD', p.path)
    resp = conn.getresponse()
    return resp.status

Иногда VPS теряет соединение, весьпри этом происходит сбой скрипта.

File "/usr/lib/python2.6/httplib.py", line 914, in request
  self._send_request(method, url, body, headers)
File "/usr/lib/python2.6/httplib.py", line 951, in _send_request
  self.endheaders()
File "/usr/lib/python2.6/httplib.py", line 908, in endheaders
  self._send_output()
File "/usr/lib/python2.6/httplib.py", line 780, in _send_output
  self.send(msg)
File "/usr/lib/python2.6/httplib.py", line 739, in send
  self.connect()
File "/usr/lib/python2.6/httplib.py", line 720, in connect
  self.timeout)
File "/usr/lib/python2.6/socket.py", line 561, in create_connection
  raise error, msg
socket.error: [Errno 101] Network is unreachable

Я совсем не знаком с обработкой ошибок, подобных этой в python.

Как правильно предотвратить сбой скрипта при подключении к сетивременно потерян?


Редактировать:

Я закончил с этим - обратная связь?

def checkUrl(url): # Only downloads headers, returns status code.
    try:
        p = urlparse(url)
        conn = httplib.HTTPConnection(p.netloc)
        conn.request('HEAD', p.path)
        resp = conn.getresponse()
        return resp.status
    except IOError, e:
        if e.errno == 101:
            print "Network Error"
            time.sleep(1)
            checkUrl(url)
        else:
            raise

Я не уверен, что полностью понимаю, что делает рейз, хотя..

Ответы [ 3 ]

4 голосов
/ 31 октября 2011

Проблема вашего решения в его нынешнем виде заключается в том, что вам не хватит места в стеке, если в одном URL-адресе слишком много ошибок (по умолчанию> 1000) из-за рекурсии. Кроме того, дополнительные кадры стека могут затруднить чтение трассировок (500 вызовов checkURL). Я бы переписал его так, чтобы он был повторяющимся, например:

def checkUrl(url): # Only downloads headers, returns status code.
    while True:
        try:
            p = urlparse(url)
            conn = httplib.HTTPConnection(p.netloc)
            conn.request('HEAD', p.path)
            resp = conn.getresponse()
            return resp.status
        except IOError as e:
            if e.errno == 101:
                print "Network Error"
                time.sleep(1)
        except:
            raise

Кроме того, вы хотите, чтобы последнее предложение в вашем try было голым except, а не else. Ваш else выполняется только в том случае, если управление падает через набор try, что никогда не может произойти, поскольку последний оператор набора try является return.

Это очень легко изменить, чтобы разрешить ограниченное количество попыток. Просто измените строку while True: на for _ in xrange(5) или сколько угодно повторных попыток. Затем функция вернет None, если не сможет подключиться к сайту после 5 попыток. Вы можете заставить его вернуть что-то еще или вызвать исключение, добавив return или raise SomeException в самом конце функции (с отступом, равным строке for или while).

3 голосов
/ 31 октября 2011

Если вы просто хотите обработать эту Сеть недоступна 101, и пусть другие исключения выдают ошибку, вы можете, например, выполнить следующее.

from errno import ENETUNREACH

try:
    # tricky code goes here

except IOError as e:
    # an IOError exception occurred (socket.error is a subclass)
    if e.errno == ENETUNREACH:
        # now we had the error code 101, network unreachable
        do_some_recovery
    else:
        # other exceptions we reraise again
        raise
0 голосов
/ 31 октября 2011

поместите try ... except: вокруг вашего кода, чтобы перехватить исключения.

http://docs.python.org/tutorial/errors.html

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