IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Gestion des erreurs. Message personnalisé


Sujet :

Langage PHP

  1. #1
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut Gestion des erreurs. Message personnalisé
    Bonjour (bonsoir) à tous

    Je cherche un moyen de mieux structurer une gestion des erreurs, particulièrement avec une classe étendue de PDO.
    J'estime que mon code n'est pas zen du tout à ce niveau même si au bout j'ai un rendu correcte.

    Le but est de pouvoir personnaliser le retour d'erreur "PDOException" en transmettant la requête SQL, le tout assez proprement.
    Dans le cas présent je transmet la requête (message perso) à l'aide d'un 6ème paramètre ...
    Question : Comment faire autrement ?


    Le code est le suivant : (je simplifie pour éviter un surplus de code inutile)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // On défini la fonction personnelle de la gestion des erreurs
    set_error_handler('erreur2Exception');
    La fonction de la gestion des erreurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    function erreur2Exception($code, $message, $file, $line, $context = null, $msessage_perso = null) {
    	$MyException = new MyException($code, $message, $file, $line, $context = null, $msessage_perso);
    	$MyException->setNiveauErreur();
    	$MyException->writeErreur();
    	echo $MyException->afficherErreur();
    }
    // C'est ce 6ème paramètre qui me semble pas zen, c'est l'astuce que j'utilise pour le moment

    La classe perso des exceptions
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    class MyException extends Exception {
    	public function __construct ($code, $message, $file, $line, $context = null, $message_perso = null) {
    		$this->code = $code;
    		$this->message = $message;
    		$this->file = $file;
    		$this->line = $line;
    		// Toujours ce 6ème paramètre
    		$this->message_perso = $message_perso;
    	}
     
    	public function afficherErreur() {
    		$str .= '<br />['.date("d/m/Y H\hi:s").'][Code : '.$this->getCode().']['.$this->getNiveauErreur().'][compteur : '.self::$compteurErreur.']'.PHP_EOL;
    		$str .= '<br />Fichier : '.$this->getFile().' à la ligne : '.$this->getLine().PHP_EOL;
    		$str .= '<br />'.$this->getMessage().PHP_EOL;
    		if (!empty($this->message_perso)) {
    			$str .= '<br />'.$this->message_perso.PHP_EOL;
    		}
    		return $str;
    	}
    }
    Exemple d'une méthode de la classe étendue PDO
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class PdoMySQL extends PDO {
     
    	public function prepare($statement, $array = array()) {
    		self::$query = $statement;
    		try {
    			return parent::prepare(self::$query);
    		}
    		catch (PDOException $e) {
    			MysqlDebug::debugErreur($e);
    		}
    	}
    }
    Enfin, la classe permettant le debuggage, et transmettre la requête SQL
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    class MysqlDebug {
    	protected static $debug = array(); // Requêtes dans un tableau
    	protected static $counter = 0;     // Compteur pour le débuggage
    	//
     
    	public static function debugErreur($exception) {
    		$trace = $exception->getTrace();
    		$pageErr = $trace[1]['file'];
    		$ligneErr = $trace[1]['line'];
     
    		$msg_perso = '';
    		$query = PdoMySQL::getQuery();
    		if (!empty($query)) {
    			$msg_perso = 'Requête :<br />'.nl2br($query);
    			erreur2Exception(E_ERROR, $exception->getMessage(), $pageErr, $ligneErr, null, $msg_perso);
    		}
    	}
    }
    Tout ceci permet d'obtenir (en cas d'erreur) un message comme ceci :

    [06/02/2010 22h17:21][Code : 1][Erreur : E_ERROR][compteur : 1]
    Fichier : communs/classes/PdoMySQL.php à la ligne : 362
    SQLSTATE[42S02]: Base table or view not found: 1146 Table 'projet.essais' doesn't exist
    Requête :
    UPDATE essais SET nom = :nom
    WHERE id = :_id

    J'espère ne pas avoir été trop long et trop flou.
    Les 2 parties principales restent cependant la classe MyException et MysqlDebug.


    Merci pour toute aide et avis éclairé.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  2. #2
    Membre chevronné Avatar de nosferapti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    1 157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 157
    Points : 1 895
    Points
    1 895
    Par défaut
    Citation Envoyé par RunCodePhp Voir le message
    Question : Comment faire autrement ?
    déjà tu peux modifier la gestion des erreurs avec "set_error_handler" pour qu'une erreur soit transformée en exception avec ça par exemple :
    http://php.net/ErrorException

    ensuite une fois que cela est en place, tu n'auras plus qu'à gérer les exceptions ce qui simplifie le travaille comme là par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            try {
                return parent::prepare(self::$query);
            }
            catch (PDOException $e) {
                MysqlDebug::debugErreur($e);
            }
    que tu peux simplifier en ôtant le "try-catch" puisqu'ensuite c'est dans le système de gestion des exception que tu peux décider ce qu'il se passe :
    http://php.net/set_exception_handler
    GNAP !

  3. #3
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Re bonjour, et merci de ta réponse nosferapti.

    Effectivement, je n'avais pas utilisé de set_exception_handler() pour la simple raison que je n'avais pas compris l'intérêt.

    Je tente de comprendre comment tout ceci ce goupille en suivant les liens que tu as fourni.

    Je remarque effectivement que le set_exception_handler('exception_handler') permet de capturer l'erreur dans la classe PdoMySQL, et sans les try/catch

    En faisant un var_dump je reçois bien une exception PDOException dans la fonction exception_handler($exception)
    C'est déjà magnifique


    Il reste néanmoins un truc que je ne pige pas, c'est que tout le script s'arrête au niveau de cette erreur, comme si c'était une erreur fatal.

    Faire une erreur sur le nom d'une table par exemple me semble pas une erreur fatal, tout au plus une erreur de type USER_ERROR, donc normalement Php devrait continuer à interpréter le reste.
    Ca m'embête ce comportement quand même.


    Bon, je continu de faire des essais.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  4. #4
    Membre chevronné Avatar de nosferapti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    1 157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 157
    Points : 1 895
    Points
    1 895
    Par défaut
    Citation Envoyé par RunCodePhp Voir le message
    Faire une erreur sur le nom d'une table par exemple me semble pas une erreur fatal, tout au plus une erreur de type USER_ERROR, donc normalement Php devrait continuer à interpréter le reste.
    Ca m'embête ce comportement quand même.
    si tu as une exception non bloquante, tu peux utiliser "try catch" à ce moment
    l'avantage des exceptions c'est que tu ne dois pas mettre cette gestion de l'exception obligatoirement autour de l'appel de "PDO::prepare()" tu peux mettre le "try catch" par exemple autour d'un seul appel de "PdoMySQL::prepare()" ou bien encore dans une classe qui utilise cet appel

    l'autre avantage c'est que tu peux étendre une exception et par exemple avoir PDOExceptionInsertion, PDOExceptionSelection ou PDOExceptionSuppression et faire des opérations différentes suivant le type d'exception
    GNAP !

  5. #5
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    l'avantage des exceptions c'est que tu ne dois pas mettre cette gestion de l'exception obligatoirement autour de l'appel de "PDO::prepare()" ...

    l'autre avantage c'est que tu peux étendre une exception et par exemple avoir PDOExceptionInsertion, PDOExceptionSelection ou PDOExceptionSuppression et faire des opérations différentes suivant le type d'exception.
    J'ai bien pris note de tes remarques

    Grâce à ton aide, il me semble avoir mieux compris le mécanisme des exceptions, de leur intérêts.

    Si ce n'est pas abuser, je souhaiterais ton avis (ou autre) pour savoir si j'ai bien compris.

    En 1er, et suite à ce qui est dit ici : set_exception_handler cette fonction serait pour capturer toutes erreurs non traitées par un try/catch dans une fonction ou classe, ce serait le "dernier recourt" si on peu dire pour traiter l'erreur.

    Ensuite, et pour continuer sur mon exemple d'erreur sur le nom d'une table et dans la méthode PdoMysql::execute(), il ne faudrait pas mettre de try/catch, laisser en quelque sorte le set_exception_handler() capturer une erreur éventuelle.

    Par contre, je pourrais faire un code du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    class PdoStmt extends PDOStatement {
     
    	protected function verifTable() {
    		// Un traitement spécifique
    		if ( la vérification == false ) throw new PDOException( La table trucmuche n existe pas );
    		return true;
    	}
     
    	public function execute($arr = null) {
    		try {
    			$this->verifTable();
    		}
    		catch (PDOException $e) {
    			echo 'Erreur capturée (verifTable) : '.$e->getMessage().'<br />';
    		}
     
    		return parent::execute($arr);
    	}
    }
    Donc une méthode verifTable() qui vérifierait la présence de la table (peu importe la manière).
    - Si elle existe, c'est bon (true)
    - Si elle n'existe pas, je lance un exception : throw new Exception()

    Ensuite je capture l'erreur grâce au try/catch dans le execute(), je traite l'erreur.

    Même si cet exemple est plus que simpliste, il devrait résumer comment je pourrais mieux traiter une erreur de ce type en profitant d'une gestion des erreurs un peu plus évolué.
    J'ai effectué un essai quasi similaire au code ci dessus, ça m'a l'air assez concluant.

    tu peux étendre une exception et par exemple avoir PDOExceptionInsertion, PDOExceptionSelection ou PDOExceptionSuppression ...
    Petite précision.
    Si je vais sur cette voix là, serait des classes étendues de Exception ou de PDOException ?
    Théoriquement de PDOException, non ?


    Encore merci
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

Discussions similaires

  1. [WD17] Gestion des langues (message d'erreur et interface)
    Par cladoo dans le forum WinDev
    Réponses: 0
    Dernier message: 12/10/2012, 10h51
  2. [struts][Datasource]Gestion des erreurs
    Par GreenJay dans le forum Struts 1
    Réponses: 8
    Dernier message: 15/09/2004, 16h51
  3. [VB6] Gestion des erreurs dans une dll
    Par zimba-tm dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 02/08/2004, 11h20
  4. [XSLT]Est ce qu'il y'a la gestion des erreur en xslt ?
    Par miloud dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 04/02/2004, 17h19
  5. [LG]gestion des erreurs
    Par frontin dans le forum Langage
    Réponses: 3
    Dernier message: 29/11/2003, 22h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo