63 votes

Quelles erreurs / exceptions dois-je gérer avec urllib2.Request / urlopen?

J'ai le code suivant pour faire une publication à une URL distante:

request = urllib2.Request('http://www.example.com', postBackData, { 'User-Agent' : 'My User Agent' })

try: 
    response = urllib2.urlopen(request)
except urllib2.HTTPError, e:
    checksLogger.error('HTTPError = ' + str(e.code))
except urllib2.URLError, e:
    checksLogger.error('URLError = ' + str(e.reason))
except httplib.HTTPException, e:
    checksLogger.error('HTTPException')

Le postBackData est créé à l'aide d'un dictionnaire codé à l'aide de urllib.urlencode. checksLogger est un enregistreur à l'aide de la journalisation.

J'ai eu un problème de ce code s'exécute lorsque le serveur distant est en baisse et le code de sorties (ce qui est au client de serveurs, donc je ne sais pas ce que la sortie de vidage de pile / erreur est à ce moment). Je suppose que c'est parce qu'il est une exception et/ou de l'erreur, qui n'est pas traitée. Alors y at-il d'autres exceptions qui pourraient être déclenchés que je ne suis pas de la manipulation ci-dessus?

65voto

vartec Points 53382

Ajouter un gestionnaire d'exception générique:

 request = urllib2.Request('http://www.example.com', postBackData, { 'User-Agent' : 'My User Agent' })

try: 
    response = urllib2.urlopen(request)
except urllib2.HTTPError, e:
    checksLogger.error('HTTPError = ' + str(e.code))
except urllib2.URLError, e:
    checksLogger.error('URLError = ' + str(e.reason))
except httplib.HTTPException, e:
    checksLogger.error('HTTPException')
except Exception:
    import traceback
    checksLogger.error('generic exception: ' + traceback.format_exc())
 

20voto

DNS Points 17577

À partir de la docs page urlopen entrée, on dirait que vous juste besoin de rattraper URLError. Si vraiment vous voulez couvrir vos paris à l'encontre des problèmes au sein de la urllib code, vous pouvez également attraper Exception comme un recul. Ne pas juste except:, depuis l'attraper SystemExit et KeyboardInterrupt également.

Edit: Ce que je veux dire, c'est que vous êtes capture des erreurs qu'il est censé jeter. Si c'est jeter quelque chose d'autre, c'est probablement dû à urllib code pas attraper quelque chose qu'il doit avoir pris et enveloppé dans un URLError. Même les stdlib tend à manquer des choses simples comme AttributeError. Attraper Exception comme un recul (et de la journalisation de ce qu'il a attrapé) pour vous aider à comprendre ce qui se passe, sans piégeage SystemExit et KeyboardInterrupt.

15voto

Steven Huwig Points 8029
$ grep "raise" /usr/lib64/python/urllib2.py
IOError); for HTTP errors, raises an HTTPError, which can also be
        raise AttributeError, attr
                raise ValueError, "unknown url type: %s" % self.__original
        # XXX raise an exception if no one else should try to handle
        raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
        perform the redirect.  Otherwise, raise HTTPError if no-one
            raise HTTPError(req.get_full_url(), code, msg, headers, fp)
                raise HTTPError(req.get_full_url(), code,
            raise HTTPError(req.get_full_url(), 401, "digest auth failed",
                raise ValueError("AbstractDigestAuthHandler doesn't know "
            raise URLError('no host given')
            raise URLError('no host given')
            raise URLError(err)
        raise URLError('unknown url type: %s' % type)
        raise URLError('file not on local host')
            raise IOError, ('ftp error', 'no host given')
            raise URLError(msg)
            raise IOError, ('ftp error', msg), sys.exc_info()[2]
            raise GopherError('no host given')

Il y a aussi la possibilité d'exceptions dans urllib2 dépendances, ou des exceptions causée par de véritables bugs.

Vous êtes mieux lotis de la journalisation de toutes les exceptions non traitées dans un fichier via un custom sys.excepthook. La clé de la règle d'or ici est de ne jamais attraper les exceptions que vous ne prévoyez pas de les corriger, et l'enregistrement n'est pas une correction. Afin de ne pas attraper juste pour se connecter entre eux.

1voto

Eugene Morozov Points 4417

Vous pouvez intercepter toutes les exceptions et enregistrer ce qui est intercepté:

  import sys
 import traceback
 def formatExceptionInfo(maxTBlevel=5):
     cla, exc, trbk = sys.exc_info()
     excName = cla.__name__
     try:
         excArgs = exc.__dict__["args"]
     except KeyError:
         excArgs = "<no args>"
     excTb = traceback.format_tb(trbk, maxTBlevel)
     return (excName, excArgs, excTb)
 try:
     x = x + 1
 except:
     print formatExceptionInfo()
 

(Code de http://www.linuxjournal.com/article/5821 )

Lisez également la documentation sur sys.exc_info .

0voto

Corey Goldberg Points 15625

J'attrape:

httplib.HTTPException
urllib2.HTTPError
urllib2.URLError

Je crois que cela couvre tout, y compris les erreurs de socket.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X