Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Slt,
je me pose la question concernant la gestion des exceptions.
Lorsque dans une action, suite à un contrôle de variable envoyée par POST dans un formulaire, je vois qu'il y a un problème, tout naturellement, j'ai envie de lancer une exception.
Cependant, si je fais ça, ben cette exception est catchée par la page index.php : j'affiche bien le message mais l'affichage est un peut brute...En fait, il faudrait que cette exception soit catchée par le controller parent de mon controller qui lance l'exception...
Comment faites vous pour gérer les exceptions dans les actions?
(Cf. Struts pour ceux qui connaissent)
Yoong
Hors ligne
Pour moi les exceptions sont des problèmes d'ordre technique.
Hors un erreur de formulaire utilisateur n'est pas un problème technique mais une erreur "normale" dans le sens où le programme est là exprès pour traiter des saisies utilisateurs.
PS: je ne connais pas Struts.
Hors ligne
je suis d'accord une saisie erroné de l'utilisateur est un fonctionnement normal de l'application
pas une erreur.
A+JYT
Hors ligne
Slt,
je crois que nous n'avons pas la même définition du mot exception : lever une exception dans un programme objet est justement le comportement normal (cf. documentation sur la programmation objet).
Donc lever une exception suite à un contrôle de données est tout à fait normal et même fortement recommandé dans la programmation objet. Donc, je ne sais pas comment vous faites alors si vous ne levez pas des exceptions pour traiter les données erronnées?
Ne pas confondre exception et erreur : une exception est en quelque sorte une erreur prévue par le programme alors qu'une erreur est une exception non prévue, un bug quoi!
Yoong
Hors ligne
si tu considère qu'une erreur de formulaire est une exception. tu surcharges la classe Exception.
))
pourquoi ne pas catché au niveau du controlleur ?
je vois pas spécialement ou est le soucis (j'ai jamais tenté cette approche mais elle peut etre interessante )
class formException extends Exception{ } class formEmptyException extends formException{ } class formNaNException extends formException{ }
Au niveau de ton controleur
try{ if ( empty($_POST['maVar']) ){ throw new formEmptyException('maVar est non renseigné'); }elseif( ! is_numeric($_POST['maVar']) ){ throw new formNaNException('maVar n\'est pas une valeur numerique'); } }catch(formException $e){ // erreur prévue associable à maVar $myView->errorMaVar = $e->getMessage(); }catch(Exception $e){ // erreur non prévue non associable à maVar $myView->errorForm = $e->getMessage(); }
Dernière modification par ndesaleux (04-03-2008 23:46:04)
Hors ligne
Je me pose justement des questions en ce moment sur la gestion des erreurs.
J'ai mis en place un pluggin qui gère les exception.
Le tuto que j'ai utilisé http://julien-pauli.developpez.com/tuto … ceptions2/
semblait conseiller de traiter les erreurs métiers dans le controller/action associé au pluggin :
<?php class ErrorController extends Zend_Controller_Action { private $_exception; private static $errorMessage; private static $httpCode; public function preDispatch() { $this->_helper->viewRenderer->setNoRender(true); // ne rend aucune vue automatiquement $this->_exception = $this->_getParam('error_handler'); $this->_response->clearBody(); // on vide le contenu de la réponse $this->_response->append('error',null); // on ajoute un segment 'error' dans la réponse switch ($this->_exception->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: self::$httpCode = 404; self::$errorMessage = 'Page introuvable'; break; case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER: switch (get_class($this->_exception->exception)) { case 'Zend_View_Exception' : self::$httpCode = 500; self::$errorMessage = 'Erreur de traitement d\'une vue'; break; case 'Zend_Db_Exception' : self::$httpCode = 503; self::$errorMessage = 'Erreur de traitement dans la base de données'; break; case 'Metier_Exception' : self::$httpCode = 200; self::$errorMessage = $this->_exception->exception->getMessage(); break; case 'Autre_Exception' : self::$httpCode = 500; self::$errorMessage = 'Exemple avec une "autre exception"'; break; default: self::$httpCode = 500; self::$errorMessage = 'Erreur inconnue'; break; } break; } } public function errorAction() { $this->getResponse()->setHttpResponseCode(self::$httpCode); $this->_errorMessage .= sprintf("<p>%s</p>",self::$errorMessage); } public function postDispatch() { $this->getResponse()->appendbody($this->_errorMessage,'error'); $this->getResponse()->appendbody('<a href="javascript:history.back()">retour</a>','error'); if (Zend_Registry::get('config')->debug == 'true') { $message = sprintf('<hr>DEBUG INFOS :<br /><strong>Exception de type <em>%s</em> <u>%s</u> envoyée dans %s à la ligne %d </strong> <p>Stack Trace : %s </p><hr>', get_class($this->_exception->exception), $this->_exception->exception->getMessage(), $this->_exception->exception->getFile(), $this->_exception->exception->getLine(), Zend_Debug::dump($this->_exception->exception,null,false) ); $this->getResponse()->append('debug',$message); } } }
On voit qu'il est prévu de gérer les erreurs métiers :
case 'Metier_Exception' : self::$httpCode = 200; self::$errorMessage = $this->_exception->exception->getMessage(); break;
Je me demande si je dois faire le même chose. Je suis en train de mettre en place la gestion d'une erreur 'Acces non autorisé':
if (!$this->_acl->isAllowed($this->_role,$resource)) { ??? }
Ça me parait étrange de gérer ca dans le controller/action associé au pluggin vu qu'il se base sur une exception et que dans ce cas, il n'ya pas exception.
Du coup, j'ai envie de garder cette action uniquement pour les exceptions et de gérer les erreurs métiers dans une autre action.
Ca donnerai quelque chose du genre :
if (!$this->_acl->isAllowed($this->_role,$resource)) { $request->setControllerName('error'); $request->setActionName('errorMetier'); $request->setParam('error',1); //erreur 1 = Accès non autorise }
Qu'en pensez vous ?
Comment gérez vous les erreurs métier ?
Hors ligne
kiminox a écrit:
Slt,
je crois que nous n'avons pas la même définition du mot exception : lever une exception dans un programme objet est justement le comportement normal (cf. documentation sur la programmation objet).
Donc lever une exception suite à un contrôle de données est tout à fait normal et même fortement recommandé dans la programmation objet. Donc, je ne sais pas comment vous faites alors si vous ne levez pas des exceptions pour traiter les données erronnées?
Ne pas confondre exception et erreur : une exception est en quelque sorte une erreur prévue par le programme alors qu'une erreur est une exception non prévue, un bug quoi!
Yoong
non comme son nom l'indique lever une exception sert à passer dans un mode de traitement applicatif exceptionnel.
c'est justement un mode de rattrapage d'erreur.
lever une exception ne doit se faire que lorsqu'on se trouve dans une situation que l'on ne peut pas résoudre.
vérifier que l'utilisateur à bien saisie une date n'a rien exceptionnel.
tenter d'acceder à une ressource qui normalement devrait être là et qui ne réponds pas est une situation exceptionnelle.
par exemple la méthode query de Zend_Db_Adapter doit accéder à une ressoure SQL si celle-ci ne réponds pas la fonction n'a aucune solution à proposer elle l'ève une exception pour dire qu'il se passe quelque chose d'anormal à l'appelant de tenter de résoudre le problème. l'exception reste active d'appelant en appelant jusqu'à trouver un niveau qui sais quoi faire.
si aucun gestionnaire d'évènement n'est présent alors il y a un bug c'est une situation qui ne doit pas arriver.
mais la ressource indisponible n'est pas une erreur c'est une situation exceptionnelle.
le format de la date de saisie n'a rien d'exceptionnel. cela fait partie du dialogue normal avec le client.
à l'opposé une utilisation frauduleuse d'une fonction ne dois pas entrainer la levée d'une exception. mais une erreur fatale. c'est un BUG le développeur Doit respecter le contrat d'interface de la fonction s'il ne le fait pas ça ne sert à rien de lever une exception c'est un BUG et il est impossible de récupérer ses petit sur un bug donc on lève alors une erreur.
A+JYT
Hors ligne
sekaijin,
En effet, en Java, nous utilisons les exceptions pour controler les erreurs de traitement, tant métier (une champ date doit par exemple être renseigné ou doit être dans un format donné, même si un contrôle est déjà effectué au niveau client javascript) que fonctionnel (un sous-produit doit être associé à un produit par exemple).
Les exceptions non traitées (bug donc) sont capturées en dernier recours par le système pour avertir l'utilisateur (et le service de maintenance par exemple par mail) afin d'être traitées. Evidemment, il y a plusieurs niveaux d'exception. Mais en aucune façon une exception ou une erreur ne doit donner lieu à une erreur fatale : c'est alors un bug grave!
D'ailleurs, à ce propos Php n'est pas très bien adapté : malgré mon gestionnaire d'erreur, si j'instancie une classe avec deux méthodes portant le même nom, ben tout plante, plus rien ne s'affiche! (je sais bien qu'il n'est pas possible de définir deux méthodes avec des signatures différentes puisque php n'est pas un langage typé)
Pour débugguer, c'est la galère!
Comment faites vous dans ces cas là?
Yoong
Hors ligne
de mémoire, si tu as activé l'affichage des erreurs avec error_reporting(E_ALL) tu dois avoir un message t'indiquant que tu as plusieurs définitions d'une methode.
Mettre error_reporting(E_ALL) est indispensable en face de dev, voire en phase de recette. Après un simple log des erreurs dans un fichier avec envoi régulier suffit à faire remonter les erreurs non-découverte/non-prévues et donc à les corriger.
En php, la surcharge de méthode est impossible, donc ceux qui ont l'habitude de coder avec ce language font rarement ce type d'erreur (pour ne pas dire jamais ).
C'est sur que les developpeurs provenant de language fortement typé doivent perdre certains habitudes comme celle de surchargé des méthodes.
Hors ligne
Bon, moi de mon cote j'en conclu que je dois gérer les erreurs a un autre endroit que dans le contrôler/action du plugin qui gère les exceptions.
Hors ligne