Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Gestion d'erreurs dans python

36 réponses
Avatar
ian
Bonjour,

Ayant donne la chance a python (contre l'avis de la direction... :p) il
s'avere que j'ai eu raison ... Nous avons d'excellents resultats en terme de
dev, de vitesse (c'etait la principale crainte) et il tient ses promesses:
on peut utiliser le meme code sur PC X86 comme sur le materiel embedded,
qu'il soit en SH3 ou en ARM ... La classe! :)

Maintenant, une question : la gestion des erreurs. Quand ca plante quelque
part, il indique l'erreur etcetc, le module qui a plante ne tourne plus,
mais le reste si, ce qui donne une impression que le soft tourne toujours
mais avec une partie en moins.. Pas pratique.
Je me suis dit qu'il devait y avoir un parametre a passer a python pour
qu'il sorte (ou relance) automatiquement a la moindre erreur, stype
python -onerrorrestart xxx.pyc, vous voyez le genre .. et la, dans la doc,
horreur, je trouve rien...

Donc, comme il est impossible de tout prevoir, et que je ne peux pas mettre
de try catch partout, existe-t-il un moyen de dire a python de fermer ou
relancer le soft des qu'une erreur (grave ou non) apparait ?

Merci

6 réponses

1 2 3 4
Avatar
Bertrand B
.

Je trouve try/except moins lourd que le traitement au cas par cas - les
gouts et les couleurs...

Et comme ça, quand les exceptions remontent, c'est qu'il n'y a pas de
traitement d'erreur à faire (ou que le développeur a écrit du cod e
jetable sans traitement d'erreur).
Mais en tout cas elles ne sont pas passées sous silence (ce qui a des
effets indésirables à postériori nettement plus difficiles à ce rner).
C'est pour cette raison qu'on conseill de ne jamais mettre en place de
filtre except "catchall" de façon inconsidérée.

Ok


La méthode à la perl amène
finalement à une meilleur fiabilité puisque le programmeur doit pe nser à
traiter ou commenter précisément chaque cas d'anomalie.


Là, je ne suis pas d'accord. J'ai fait pas mal de C (en plus du C++), où
il faut gérer les erreurs de cette façon [*]. Sauf à avoir des
développeurs très expérimentés et qui blindent leur code - rare - on
retrouve généralement des codes de retour non traités...

Tout à fait

Ben, tu ajoutes un décorateur à ta fonction, avec un bloc try/excep t
autour de l'appel à la fonction et zoooo.

Là il faudra que je me repenche sur les décorateurs mais python avanc e

plus vite que je ne pers de neurones.





Avatar
NicolasP
Pour quoi faire ? Ce n'est pas parce qu'une fonction lève une
exception qu'il faut rattraper cette exception à ce niveau là (si tu
sais gérer l'exception au niveau de la fonction, tu ne la laisse pas
se propager, donc si tu la laisse se propager c'est que ce n'est
précisément pas le bon endroit pour la gérer, cqfd).


A condition de ne pas la laisser remonter par simple fainéantise.

Ok par contre la personne qui créé un module est la plus à même à
comprendre ce qui peut générer les exceptions ? Et d'y remédier ?


Imaginons que tu crées un module qui fasse des entrées/sorties sur des fichiers à un niveau bas. Il y a le traitement des données mais il y a surtout les entrées/sorties sur le disque. Un module de plus haut niveau compte sur ce module de bas niveau pour faire la lecture/écriture sur le disque. Si une erreur arrive quand le fichier est écrit (un exemple parmis d'autres), que doit faire le module de bas niveau ? Eventuellement, réessayer ou essayer de contourner le problème. Mais si ça ne le fait vraiment pas ? Crois-tu vraiment que l'exception ne doit pas remonter ?



Nicolas


Avatar
Bruno Desthuilliers


Pardon ? Tu a déjà essayé d'avoir une gestion d'erreur fiable et non
intrusive avec un langage n'ayant pas de support pour les exceptions ?

Je n'ai pas dit ça enfin ;)


Qui a dit qu'il fallait les gérer "au plus près" ? Le bon endroit pour
gérer une exception, c'est là où on a le contexte nécessaire pour la
gérer - ce qui est très différent de "au plus près".



On m'aurait donc menti ?
plus sérieusement il y a un peu trop de modules qui laissent remonter
des exceptions sans les traiter.


En général, c'est parce que le concepteur du module ne *peut pas* savoir
à l'avance comment l'utilisateur dudit va vouloir gérer le problème -
car cela dépend du contexte dans lequel ladite fonction est utilisée.

Dans la pratique, j'ai plus souvent eu des problèmes avec des modules
qui en faisaient trop sur la gestion d'erreur que l'inverse.

Je n'ai pas la prétention d'être un king de la programmation n'y d'avoir
les bonnes habitudes.
Par contre celle de poser toutes les questions y compris les plus c....


La méthode à la perl amène finalement à une meilleur fiabilité
puisque le programmeur doit penser à traiter ou commenter précisément
chaque cas d'anomalie.


Mdr.

C'est déjà ça

gestion d'erreur à la Perl:
fait_quelquechose ou crashe("ça n'a pas marché")

pas faux



Et totalement inutile. En Python, sur une exception non gérée, tu aura
le même résultat effectif (crash du programme), mais avec un message
d'erreur beaucoup plus utile (le traceback).

Pour quoi faire ? Ce n'est pas parce qu'une fonction lève une
exception qu'il faut rattraper cette exception à ce niveau là (si tu
sais gérer l'exception au niveau de la fonction, tu ne la laisse pas
se propager, donc si tu la laisse se propager c'est que ce n'est
précisément pas le bon endroit pour la gérer, cqfd).


A condition de ne pas la laisser remonter par simple fainéantise.




Ok par contre la personne qui créé un module est la plus à même à
comprendre ce qui peut générer les exceptions ? Et d'y remédier ?


Non, pas forcément. cf la réponse de NicolasP (j'allais donner un
exemple à peu près similaire). Si on prend son exemple, le code client
peut être par example un client GUI ou un serveur HTTP. Dans le premier
cas, la bonne chose à faire en cas de pépin est de prévenir
l'utilisateur et de lui proposer une solution possible, puis
éventuellement de relancer le traitement. Dans le second, logger
l'exception et retourner un 500 puis au choix attendre la requête
suivante ou essayer de se terminer proprement. C'est justement tout
l'intérêt des mécanismes d'exception: permettre de déporter le
traitement de l'erreur vers l'endroit où on a le meilleurs contexte pour
la gérer.


Ou un bloc exception en fin des blocs de définitions de fonctions.


OOh, oui, génial. Comme les 'on error go to...' de VB ?



Ouii pourquoi pas


parce que c'est une horreur ingérable ?-)

PS: c'est quoi VB ?


Microsoft Visual Basic. Une horreur.



Avatar
Laurent Pointal
<zip>
Là, je ne suis pas d'accord. J'ai fait pas mal de C (en plus du C++), où
il faut gérer les erreurs de cette façon [*]. Sauf à avoir des
développeurs très expérimentés et qui blindent leur code - rare - on
retrouve généralement des codes de retour non traités...


Et un exemple. Pas en C ni en Python, mais en PHP.
http://www.easybourse.com/Website/dynamic/News.php?NewsID3176&lang=fra&NewsRubrique=1&pageliste
Cas typique du non-traitement des erreurs. La connexion échoue, chose
possible et à prévoir, et au lieu d'avoir une info propre "problème
technique, merci de contacter blabla...", le script continue à se
dérouler et à essayer d'atteindre des données via une connection
invalide, générant tout plein d'autres erreurs non traitées elles-aussi.

Accessoirement, les sorties d'erreurs ne devraient pas se retrouver sur
la page (à défaut d'un fichier de log, PHP pourrait se fendre de les
mettre dans des commentaires HTML pour que l'utilisateur n'y soit pas
directement confronté).



Note: ça reviendra peut-être dans qq temps, mais pour le moment à l'URL
indiquée j'ai la sortie suivante:

Du contenu correct +

Warning: mysql_connect() [function.mysql-connect]: Can't connect to
MySQL server on '89.107.169.5' (111) in
/home/sites_web/www.easybourse.com/_lib.php on line 9

Warning: mysql_select_db(): supplied argument is not a valid MySQL-Link
resource in /home/sites_web/www.easybourse.com/_lib.php on line 10

Warning: mysql_query(): supplied argument is not a valid MySQL-Link
resource in /home/sites_web/www.easybourse.com/Website/dynamic/News.php
on line 21

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL
result resource in
/home/sites_web/www.easybourse.com/Website/dynamic/News.php on line 22

Warning: mysql_query(): supplied argument is not a valid MySQL-Link
resource in /home/sites_web/www.easybourse.com/_lib.php on line 836

Warning: session_start() [function.session-start]: Cannot send session
cookie - headers already sent by (output started at
/home/sites_web/www.easybourse.com/_lib.php:9) in
/home/sites_web/www.easybourse.com/AdminB/Template/Page/__SessionStart.php
on line 5

Warning: session_start() [function.session-start]: Cannot send session
cache limiter - headers already sent (output started at
/home/sites_web/www.easybourse.com/_lib.php:9) in
/home/sites_web/www.easybourse.com/AdminB/Template/Page/__SessionStart.php
on line 5

Warning: mysql_connect() [function.mysql-connect]: Can't connect to
MySQL server on '89.107.169.5' (111) in
/home/sites_web/www.easybourse.com/AdminB/Template/Page/CreationCookie.php
on line 3

Warning: mysql_select_db(): supplied argument is not a valid MySQL-Link
resource in
/home/sites_web/www.easybourse.com/AdminB/Template/Page/CreationCookie.php
on line 4


Warning: mysql_query(): supplied argument is not a valid MySQL-Link
resource in
/home/sites_web/www.easybourse.com/Website/dynamic/NewsContenu.php on
line 97

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL
result resource in
/home/sites_web/www.easybourse.com/Website/dynamic/NewsContenu.php on
line 98

Warning: mysql_query(): supplied argument is not a valid MySQL-Link
resource in
/home/sites_web/www.easybourse.com/Website/dynamic/NewsContenu.php on
line 104

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL
result resource in
/home/sites_web/www.easybourse.com/Website/dynamic/NewsContenu.php on
line 105

Avatar
Paul Gaborit
À (at) Tue, 27 Mar 2007 11:34:17 +0200,
Bruno Desthuilliers écrivait (wrote):
[...]
La méthode à la perl amène finalement à une meilleur fiabilité
puisque le programmeur doit penser à traiter ou commenter
précisément chaque cas d'anomalie.


Mdr.

gestion d'erreur à la Perl:
fait_quelquechose ou crashe("ça n'a pas marché")

C'est du Garcimore, ta gestion d'erreur. Le résultat final est
exactement le même que celui d'une exception non gérée (traceback en
moins). C'est toi qui parles de "fiabilité" ?


Juste une remarque : le 'die' de Perl (traduit ici par 'crashe') est
en fait un générateur d'exception (on peut très bien lui passer comme
argument un objet plutôt qu'un simple message). Et les blocs
try/catch(throw) sont en fait des blocs eval/if($@)(die).

Un appel à 'die' en Perl n'est donc pas ce qu'on appelle de la gestion
d'erreur mais juste la détection. Pour le 'traceback', on peut
modifier le fonctionnement de 'die' pour avoir une trace complète de
la pile.

À mon avis, quelque soit le langage, aucun programmeur sérieux ne peux
réellement remettre en cause l'intérêt des exceptions pour la gestion
propre des erreurs.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>


Avatar
fleur-mal
NicolasP a écrit le 08/03/2007 à 11h00 :
Là, je ne suis pas d'accord.
Je programme quasiment que sur de l'embarqué. Et en embarqué,
il faut
considérer que rien n'est acquis. Par exemple, c'est pas parce qu'un
fichier


s'est ouvert que l'on pourra le lire ou l'écrire à
volonté. Les ressources
sont limitées, l'environnement hostile et l'utilisateur
imprévisible.
J'ai du mal à faire passer le message aux informaticiens
habitués à la
programmation sur PC où ils considèrent que presque tout est
possible sans


gestion d'erreur. Et ça pose de vrais problèmes. C'est vrai que
c'est
beaucoup plus lourd de gérer les erreurs correctement mais on c'est
nécessaire ET indispensable.

Je suis d'accord, mais pas d'accord sur le fait qu'on regle tout a coup de
gros try catch partout histoire de dire que c'est ok ... Comme tu dis, les
ressouces sont limitees, mais le pire pour moi c'est que mes ptites
bestioles recoivent de partout des donnees, par ethernet, par gsm (sms ou
datas), par modem, par wifi ... bref, TRES communicante, et si un des
appareils autour m'envoi des conneries, tout le reste peut partir en live
Evidemment si j'ai pas le choix jvais try catcher tout ca, mais bon


Les problèmes ne se règlent pas forcément à coup
de try/except et sûrement pas avec des gros try et des except sans
condition comme dans un de mes posts précédents (ce qu'il faut
absolument éviter).


Des simples tests pour valider une valeur de variable peuvent beaucoup
améliorer la stabilité du système.
Du genre, tu reçois une trame d'un autre appareil que tu as
conçu. Comme tu as conçu l'émetteur et le récepteur
tu sais que la trame as une taille x. Dans le récepteur, tu programmes
tout avec cette taille sans vérifier que la trame reçue as bien
la bonne taille. Erreur. La loi de Murphy dit qu'à un moment ou un
autre...
Evidemment, il est impossible de penser à toutes les sources d'erreurs
possibles.

Nicolas


bonjour,
moi même j'ai le même problème. en effet, je souhaiterais savoir si on peut récupérer les erreurs au niveau DCL (VMS) de telle façon à ce que quand on aurait une erreur notre traitement peut être arrêté et on disposeras d'une sorte de journal qui contient les erreurs enfin la cause du "plantage" et la relance du traitement.
Pour être précis, est ce qu’il est possible en PYTHON de positionner un indicateur ou autre pour récupérer les erreurs au niveau DCL (VMS)

ps: je travaille avec python sous vms
1 2 3 4