2010-04-24 6 views
3

J'ai une application qui envoie une requête HTTP GET à une URL particulière sur Internet. Mais lorsque le réseau est en panne (par exemple, pas de wifi publique - ou mon fournisseur d'accès est en panne ou quelque chose comme ça), je reçois le retraçage suivant à urllib2.urlopen:Vérifiez si Internet n'est pas accessible en Python

70, in get 
    u = urllib2.urlopen(req) 
    File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 126, in urlopen 
    return _opener.open(url, data, timeout) 
    File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 391, in open 
    response = self._open(req, data) 
    File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 409, in _open 
    '_open', req) 
    File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 369, in _call_chain 
    result = func(*args) 
    File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 1161, in http_open 
    return self.do_open(httplib.HTTPConnection, req) 
    File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 1136, in do_open 
    raise URLError(err) 
URLError: <urlopen error [Errno 8] nodename nor servname provided, or not known> 

Je veux imprimer une erreur amicale à l'utilisateur en lui disant que son réseau peut-être vers le bas au lieu de ce message d'erreur "nodename" ou "servname provided". Bien sûr, je peux attraper URLError, mais cela attraperait chaque erreur url, pas seulement celui lié à l'indisponibilité du réseau. Je ne suis pas un puriste, donc même un message d'erreur comme "Le serveur example.com ne peut pas être atteint, soit le serveur a des problèmes ou votre connexion réseau est en panne" serait bien. Comment puis-je sélectivement attraper de telles erreurs? (Pour commencer, si la résolution DNS échoue à urllib2.urlopen, cela peut raisonnablement être considéré comme inaccessibilité réseau? Si oui, comment puis-je "l'attraper" dans le bloc except?)

+1

Si je lis le sous-texte de la question correctement, il y a tellement de composants sur le voyage vers et à partir d'un serveur web que tout ce que vous pouvez dire avec certitude est que vous ne pouvez pas obtenir l'URL . Une erreur DNS n'implique pas un mauvais lien de données, ce pourrait être une panne de serveur de DNS ou un filtre de port ou à peu près n'importe quoi. Ces jours-ci, étant donné que votre routeur par défaut peut être configuré pour (par exemple) ignorer les requêtes ICMP ECHO, vous ne pouvez pas vraiment diagnostiquer les erreurs réseau pour l'utilisateur à partir de la couche d'application. – msw

Répondre

8

Vous devez placer la requête dans une instruction try/except afin que vous puissiez l'identifier et lui faire savoir.

try: 
    u = urllib2.urlopen(req) 
except HTTPError as e: 
    #inform them of the specific error here (based off the error code) 
except URLError as e: 
    #inform them of the specific error here 
except Exception as e: 
    #inform them that a general error has occurred 
+0

C'est ce que j'ai fini par utiliser, sauf que ... HTTPError devrait venir au-dessus de URLError. Si vous pouvez résoudre ce problème, je marquerai votre réponse comme correcte. –

+0

Mais j'ai URLError et HTTPError puisque les deux peuvent se produire là. –

+2

mais 'URLError' - étant une classe de base - va aussi attraper' HTTPError'. Je vais l'éditer moi-même. –

1

urllib2 - The Missing Manual a une bonne section sur la façon de gérer Les exceptions URLError et HTTPError et comment différencier les conditions qui les ont provoquées. Comment attraper URLError, puis tester l'attribut reason?

1

Si la raison ne vous intéresse pas, relancez le URLError et manipulez-le ailleurs. Vous pouvez également essayer httplib2. Son exception ServerNotFoundError répondrait probablement à vos besoins.

+0

'reason' est une instance de' socket.gaierror' qui ne se trouve dans aucun code de la bibliothèque pure Python. Essayer de trouver ... –

+0

Voici le 'documentation socket.gaierror': http://docs.python.org/dev/library/socket.html#socket.gaierror – splicer

+0

Problème: urlopen peut aussi par HTTPError (' l'exception URLError 'l'attrape aussi). Je ne sais pas si cela peut aussi jeter d'autres erreurs. –

Questions connexes