JeuWeb - Crée ton jeu par navigateur
[Débat] "or die" ou "exception" ? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [Débat] "or die" ou "exception" ? (/showthread.php?tid=4325)

Pages : 1 2 3 4 5


RE: [Debat] "or die" ou "exception"? - Pinguin - 04-09-2009

Pareil, exception sans hésiter, pour les mêmes raisons que wild-D.

Et puis erreur != arret : Je préfère afficher un message qui dit qu'il y a eu une erreur, avec les liens pour retourner a l'accueil. Je pense que les utilisateurs préfèrent voir un message d'erreur (écrit par nous bien sur, pas cellui renvoyé par défaut) plutot qu'une page blanche sans rien pouvoir faire.
Ensuite, si la define DEBUG est définie, j'affiche directement l'erreur a l'utilisateur et j'affiche toutes les requetes.

je converti même les erreurs classiques en exception.


RE: [Debat] "or die" ou "exception"? - naholyr - 04-09-2009

L'intérêt des exceptions, c'est qu'on peut les distinguer les unes des autres. Un die c'est un die, on ne peut rien en faire...

Fondamentalement "die('truc')" ou "throw new Exception('truc')" font exactement la même chose (arrêter là l'exécution, avec le message "truc"), sauf que le premier n'offre aucune souplesse alors que le second peut offrir d'autres possibilités.

Idéalement on aura dans le contrôleur principal (point d'entrée unique de l'application) un catch général qui récupère les exceptions qui n'ont pas été catchées avant, et qui en fait quelque chose, contrairement à un die() dont on ne peut strictement rien faire :
Code PHP :
<?php 
try
{

// processus général
main();

}
catch (
Exception $e)
{
// logger l'erreur $e->getException()
// accompagne éventuellemen des détails (trace d'exécution) avec $e->getTraceAsString()
// envoyer un mail
// renvoyer vers une page d'erreur générique
}

Note pour ceux que ça énerve de se trimballer des warnings et des fatal error alors que les exceptions existent, vous pouvez utiliser ce petit snippet : http://fr2.php.net/manual/fr/class.errorexception.php#89132


RE: [Debat] "or die" ou "exception"? - Argorate - 04-09-2009

Attention...

Pour ma part du moins, j'ai donné mon avis dans le contexte du sujet du topic a savoir les erreurs a la suite de mysql_query() - requete SQL - je ne parle pas de manière général, mais bien pour ce cas spécifique Wink


RE: [Debat] "or die" ou "exception"? - naholyr - 04-09-2009

Oui, et plusieurs ont répondu que die() n'était jamais une bonne solution Smile ce qui inclut mysql_query...

Pour être tout à fait franc, si dans mon boulot on croise un code avec un "or die()" on va en rigoler un bon moment...


RE: [Debat] "or die" ou "exception"? - Argorate - 05-09-2009

Tu pourrais argumenter un peu plus? Car j'ai toujours pas vu de "malus" important a cette methode...


RE: [Debat] "or die" ou "exception"? - guile - 05-09-2009

Je reprends de mon côté un argument que j'ai déjà donné : on utilise les canons.
jappelleMaFonction() or die('ouhlala');
est une notation vue qu'en PHP.
Certes quand on programme en PHP, on en utilise les spécificités.
Néanmoins, je pense à PERL, qui est ze langage truffé de spécificité et qui est, pour un novice, totalement incompréhensible...

Quand on commence à sentir une certaine professionnalisation dans sa manière de programmer, quand on passe d'un langage à un autre, on garde des habitudes, et or die() est affreux simplement à la lecture de code (ouai je sais "un gars qui comprend pas or die() est un mauvais programmeur").

Voici une version compréhensible par une grande partie des programmeurs quels que soient leurs langages de prédilection :

$result = mysql_query($maRequeteSQL);

if ($result === false || mysql_error()) {
// on gère l'erreur...
} else {
// ça marche
}

Exception ou pas, là pour moi n'est pas le problème. Il faut arrêter de gérer les scripts avec die().
L'article que j'avais cité :
http://www.phpfreaks.com/blog/or-die-must-die

Voici les arguments contre le die() :
  1. Ce n'est pas un moyen très joli pour présenter une erreur à l'utilisateur
  2. Utiliser par exemple l'appel de mysql_error() avec, comme beaucoup le font, expose des informations qui ne devraient jamais être envoyées dans un environnement de production
  3. Vous n'avez aucun moyen de traiter l'erreur
  4. Vous ne pouvez pas journaliser l'erreur
  5. Vous ne pouvez pas contrôler s'il s'agit d'informations pouvant être affichées à l'écran ou pas. Ce n'est pas gênant de faire ça sur une environnement de développement, mais certainement pas dans un environnement de production
  6. Ca vous empêche de faire un quelconque nettoyage, ça arrête le script brutalement, c'est tout.

Enfin, je conclurai mon post par ceci :
- je lis partout "utilisez les exceptions", "n'utilisez pas or die() qui est trop brutal"
- je ne trouve de "or die()" que dans les tutoriels, qui ne cherchent pas forcément à être "bien", mais juste rapide à comprendre (au moins le visiteur ne va pas attarder sa compréhension sur la gestion des exceptions)
- Loogaroo s'était lancé dans une guerre contre les erreurs mysql non gérées (le bon gros or die()) : http://loogaroo.net/category/mysql-error-stop/

Donc si tout le monde le dis, c'est qu'il doit y avoir une raison.


RE: [Debat] "or die" ou "exception"? - Argorate - 05-09-2009

Là encore tout ces arguments sont discutables, mis a part le 5 que je n'ai pas saisie.

1. la présentation à l'utilisateur est celle qu'on en fait, rien empêche de le faire dans un joli cadre etc.

2. Comme je l'ai dit, il suffit de créer sa propre fonction gérant d'un coté l'affichage client (1) et de l'autre l'affichage de mysql_error uniquement au dev. (Pas de pb de sécurité donc).

3. Une erreur n'a pas a être traité, elle ne doit pas exister: Une erreur SQL ne peut pas exister si la requêtes est bien formuler et que la BDD est a jour et sans problème interne.

4. Grâce a la fonction que l'on crée, rien empêche de faire des log, même si je pense que c'est aux joueurs de venir signaler les bugs qu'ils rencontrent (encore plus en phase de bêta test).

5. Pas compris.

6. Je n'ai pas compris ce qu'on doit nettoyer. Mais même s'il y a une tache a faire, si on appel une fonction qui fait ce traitement, je vois pas le pb.

Bref, dans toute chose il y a des pours et des contres, reste à savoir ce qui nous convient le mieux.


RE: [Debat] "or die" ou "exception"? - Sephi-Chan - 05-09-2009

(05-09-2009, 02:48 AM)Argorate a écrit : Bref, dans toute chose il y a des pours et des contres, reste à savoir ce qui nous convient le mieux.

Et toi, peux-tu nous citer les avantages du or die() ? C'est pas tout de balayer les autres arguments (de manière plus ou moins foireuse) ?

Un énorme avantage dès exceptions, c'est d'en avoir plusieurs types. Tu ne comprends pas ça car tu ne travailles avec aucun outil (au sens librairie, framework). Imagine un ORM (je donne un exemple avec ActiveRecord de Ruby mais PHP dispose de ses propres ORM, telles que Doctrine et Propel). Ça met à ta disposition une API qui te permet de faire des choses comme :


# Trouve l'utilisateur dont l'ID est 3. Renvoie une exception RecordNotFound si rien n'est trouvé.
# C'est typiquement ce qu'on aura quand l'utilisateur cherchera à consulter le profil d'un autre.
# Cette méthode lance une exception RecordNotFound si elle ne trouve rien.
@user = User.find(3)

# On incrémente le compteur d'affichage du profil de cet utilisateur.
@user.profile_display += 1

# Cette forme du save lance une exception RecordNotSaved au lieu de renvoyer
# false si l'enregistrement échoue (car l'objet n'est pas valide, par exemple).
@user.save!

Et je gère mes erreurs du côté du contrôleur frontal, comme je l'ai montré plus haut. Mon code en ressort plus propre et ma gestion des exceptions est centralisé en un point (donc simple à maintenir, sans duplication de code, etc.) sans avoir rien à faire. Avec or die() et la fonction spéciale, tu réinventes la roue.

Puis bon, à l'ère de PHP5, ne pas utiliser les exceptions alors qu'elles sont à ta disposition, alors même que PHP conseille PDO depuis un moment… Ça vaut bien le coup de faire des remarques sur les bon programmeurs


Sephi-Chan


RE: [Debat] "or die" ou "exception"? - Allwise - 05-09-2009

Citation :3. Une erreur n'a pas a être traité, elle ne doit pas exister: Une erreur SQL ne peut pas exister si la requêtes est bien formuler et que la BDD est a jour et sans problème interne.
Dans un script on ne maîtrise pas tout. Même dans un bête script qui se contente de faire des requêtes à la base de données, on n'est pas à l'abri d'une erreur : serveur MySQL surchargé ( le fameux too much connections ), table corrompue... Comment tu fais toi pour être sûr à 100% que jamais jamais jamais tu auras une erreur de ce type ? Comment pourrais-tu être à l'abri d'un crash du serveur, d'un gros afflux de trafic, d'un bug de MySql etc ? Si l'informatique était parfait au point que les erreurs n'existent pas, il n'y aurait pas de mécanismes de gestion d'erreurs.

Après, sans entrer dans le détail des deux mécanismes dont on parle ici, l'un d'eux est très limité, l'autre est plus complet et fait la même chose mais en mieux. Pourquoi le très limité serait mieux que l'autre ? Pour des situations qui exigent des arrêts purs et simples de script je comprends, mais en faire une généralité, je comprends pas, je trouve pas ça logique.

Je le redis une fois de plus, un bon programmeur c'est avant tout quelqu'un qui sait se remettre en question et qui est capable d'évoluer tout le temps, de modifier ses habitudes lorsqu'il trouve plus performant. Enfin je dis ça, je dis rien :haha:


RE: [Debat] "or die" ou "exception"? - naholyr - 05-09-2009

(05-09-2009, 02:48 AM)Argorate a écrit : 1. la présentation à l'utilisateur est celle qu'on en fait, rien empêche de le faire dans un joli cadre etc.
Lolilol "or die('<html>............" j'imagine bien tiens :lol:

Citation :2. Comme je l'ai dit, il suffit de créer sa propre fonction gérant d'un coté l'affichage client (1) et de l'autre l'affichage de mysql_error uniquement au dev. (Pas de pb de sécurité donc).
Entre :
Code PHP :
<?php 
function mysqlError($mysql_error)
{
// traitement de l'erreur :
// Affichage d'une page d'erreur non détaillée à l'utilisateur
// Envoi d'un mail au dév avec $mysql_error
// Eventuellement traitement de debug_backtrace() pour avoir le détail d'exécution (gare au memory_limit cette fonction est souvent inutilisable...)
}

function
main()
{
//...
mysql_query('...') or myFunction(mysql_error());
//...
}

//index.php
main();
Et :
Code PHP :
<?php 
function mysqlError(Exception $e)
{
// traitement de l'erreur :
// Affichage d'une page d'erreur non détaillée à l'utilisateur
// Envoi d'un mail au dév avec $e->getMessage()
// Eventuellement traitement de $e->getTraceAsString() pour avoir le détail d'exécution (aucun pb d'utilisation)
}

function
main()
{
//...
mysql_query('...') or throw new SQLException(mysql_error());
//...
}

//index.php
try
{
main();
}
catch (
SQLException $e)
{
mysqlError($e);
}

Tu vois une différence notable toi ? Je peux formater mon message correctement aussi bien avec die() qu'avec mon exception. Sauf qu'avec die() je n'ai aucun détail alors qu'avec mes exceptions j'ai :
- la possibilité de les dissocier (par exemple je pourrai lever une exception SQLSyntaxException pour dissocier un problème de construction de requête d'un problème de serveur, et traiter ces cas d'erreur différemment avec des catch distincts).
- une trace d'exécution déjà construite et exploitable très simplement pour les logs.

Citation :3. Une erreur n'a pas a être traité, elle ne doit pas exister: Une erreur SQL ne peut pas exister si la requêtes est bien formuler et que la BDD est a jour et sans problème interne.
Pas trop de problème à trouver des chaussettes à ta taille ? Je suppose que tu es Dieu, je m'incline donc.
Oui parce qu'à part un être omniscient et omnipotent, je ne vois pas qui pourra assurer que toute erreur peut toujours être évité... Même les mecs de la NASA le savent (ils passent une heure à faire des 'check' dans tous les sens avant de lancer la fusée, c'est pas pour faire joli, c'est parce qu'une erreur peut *toujours* se produire, et qu'il vaut mieux la détecter à l'avance plutôt que de croire qu'on pourra la traiter le moment venu).

Citation :4. Grâce a la fonction que l'on crée, rien empêche de faire des log, même si je pense que c'est aux joueurs de venir signaler les bugs qu'ils rencontrent (encore plus en phase de bêta test).
Idem pour les exceptions, la souplesse vue précédemment en plus.

Citation :5. Pas compris.
Il explique que die() provoque *toujours* un affichage. On peut souhaiter que l'affichage ne se produise pas toujours selon l'environnement d'exécution (je fais tourner mon appli en environnement de dév : je veux voir tous les messages, par contre en prod je veux qu'ils soient envoyés dans un fichier). Cela ne peut pas être géré si on utilise die(), alors qu'en bannissant cette fonction soit on maitrise notre output, soit on laisse PHP le faire (avec error_log et display_errors dans le php.ini selon l'environnement).
Mais bon cet argument est effectivement cassé du moment qu'on ne fait pas "or die()" mais "or fonction_perso()".

Citation :6. Je n'ai pas compris ce qu'on doit nettoyer. Mais même s'il y a une tache a faire, si on appel une fonction qui fait ce traitement, je vois pas le pb.
En effet

Citation :Bref, dans toute chose il y a des pours et des contres, reste à savoir ce qui nous convient le mieux.
C'est là que je ne suis pas d'accord :
Code PHP :
<?php 
mysql_query
() or die()
Pour : On est sûr que le traitement s'arrête là.
Contre : On ne maîtrise rien. C'est tout le script qui s'arrête, pas juste la fonction courante.
Code PHP :
<?php 
mysql_query
() or fonction()
Pour : On fait ce qu'on veut dans fonction()
Contre : On n'est pas sûr en lisant ça que fonction() stoppe l'exécution ici, et on n'est pas sûr que le traitement s'arrête là. De plus on ne choisit pas quel traitement faire, c'est fonction() et point-barre.
Code PHP :
<?php 
mysql_query
() or throw new SQLException()
Pour : On est sûr que le traitement en cours (et pas "tout le script") s'arrête là. On spécifie précisément à l'aide de la classe de l'exception quelle erreur a provoqué cet arrêt. On laisse la possibilité au processus parent soit de laisser passer l'exception, soit de la catcher lui-même pour la traiter directement = souplesse ultime.
Contre : Oblige à déclarer une classe "SQLException extends Exception {}" (oh noe, une ligne :'(((((). Oblige à ajouter "try" et "catch ()" dans le processus parent pour (oh noe, 2 lignes :'((((().


En Java l'utilisation des exceptions est *obligatoire*, c'est à dire que tout exception qui n'hérite pas de RuntimeException (qui regroupe toutes les exceptions NullPointer, DivisionByZero, etc... qui peuvent se produire tout le temps) doit être déclarée dans le prototype de la fonction, et toute fonction qui appelle cette dernière devra soit la catcher soit la déclarer elle-même dans son prototype.
Code PHP :
<?php 
void maFonction
() throws MonException
{
if (...) throw new
MonException(); // Ceci apparaissant dans le corps de ma fonction,
// throws MonException doit apparaitre dans le profil de ma fonction, sinon ça compile pas :)
}

void monAutreFonction()
{
maFonction(); // Tel quel, ça ne compilera pas :
// soit je catche MonException ici,
// soit je déclare "throws MonException" dans le profil de ma fonction
}
Quelle robustesse cela apporte au code ! Cela change vraiment la vie... Si on n'est pas forcé de souhaiter ça au PHP, on peut au moins admettre l'utilité des exceptions par rapport aux vieilles méthodes d'il y a 10 ans à coup de die()...