web-dev-qa-db-fra.com

Manière correcte d'essayer / sauf d'utiliser Python module de demandes?

try:
    r = requests.get(url, params={'s': thing})
except requests.ConnectionError, e:
    print e #should I also sys.exit(1) after this?

Est-ce correct? Y a-t-il une meilleure façon de structurer cela? Est-ce que cela couvrira toutes mes bases?

313
John Smith

Jetez un coup d'œil aux demandes documents d'exception . En bref:

En cas de problème réseau (défaillance DNS, connexion refusée, etc.), les demandes déclencheront une exception ConnectionError.

En cas de réponse HTTP invalide rare, Requests générera une exception HTTPError.

Si une demande expire, une exception Timeout est générée.

Si une demande dépasse le nombre configuré de redirections maximum, une exception TooManyRedirects est générée.

Toutes les exceptions que Requests soulève explicitement héritent de requests.exceptions.RequestException.

Pour répondre à votre question, ce que vous montrez va not ​​couvrir toutes vos bases. Vous ne détecterez que les erreurs liées à la connexion, pas celles qui expirent.

Que faire lorsque vous attrapez l'exception dépend vraiment de la conception de votre script/programme. Est-il acceptable de sortir? Pouvez-vous continuer et essayer à nouveau? Si l'erreur est catastrophique et que vous ne pouvez pas continuer, alors oui, un appel à sys.exit() est en ordre.

Vous pouvez soit attraper l'exception de classe de base, qui traitera tous les cas:

_try:
    r = requests.get(url, params={'s': thing})
except requests.exceptions.RequestException as e:  # This is the correct syntax
    print e
    sys.exit(1)
_

Ou vous pouvez les attraper séparément et faire des choses différentes.

_try:
    r = requests.get(url, params={'s': thing})
except requests.exceptions.Timeout:
    # Maybe set up for a retry, or continue in a retry loop
except requests.exceptions.TooManyRedirects:
    # Tell the user their URL was bad and try a different one
except requests.exceptions.RequestException as e:
    # catastrophic error. bail.
    print e
    sys.exit(1)
_

Comme Christian a souligné:

Si vous souhaitez que les erreurs http (par exemple 401 non autorisées) déclenchent des exceptions, vous pouvez appeler Response.raise_for_status . Cela déclenchera un HTTPError, si la réponse était une erreur http.

Un exemple:

_try:
    r = requests.get('http://www.google.com/nothere')
    r.raise_for_status()
except requests.exceptions.HTTPError as err:
    print err
    sys.exit(1)
_

Imprimera:

_404 Client Error: Not Found for url: http://www.google.com/nothere
_
620

Une suggestion supplémentaire pour être explicite. Il semble préférable d’aller du plus particulier au plus général dans la pile d’erreurs pour obtenir l’erreur désirée, afin que les erreurs spécifiques ne soient pas masquées par l’erreur générale.

url='http://www.google.com/blahblah'

try:
    r = requests.get(url,timeout=3)
    r.raise_for_status()
except requests.exceptions.HTTPError as errh:
    print ("Http Error:",errh)
except requests.exceptions.ConnectionError as errc:
    print ("Error Connecting:",errc)
except requests.exceptions.Timeout as errt:
    print ("Timeout Error:",errt)
except requests.exceptions.RequestException as err:
    print ("OOps: Something Else",err)

Http Error: 404 Client Error: Not Found for url: http://www.google.com/blahblah

contre

url='http://www.google.com/blahblah'

try:
    r = requests.get(url,timeout=3)
    r.raise_for_status()
except requests.exceptions.RequestException as err:
    print ("OOps: Something Else",err)
except requests.exceptions.HTTPError as errh:
    print ("Http Error:",errh)
except requests.exceptions.ConnectionError as errc:
    print ("Error Connecting:",errc)
except requests.exceptions.Timeout as errt:
    print ("Timeout Error:",errt)     

OOps: Something Else 404 Client Error: Not Found for url: http://www.google.com/blahblah
53
jouell