Bonjour,
Je me permet de rebondir sur le sujet.
Je crée en ce moment même un gestionnaire d'erreur ET un gestionnaire d'exception en POO.
Pour le gestionnaire d'erreur ça va très bien. J'ai même fait en sorte qu'une erreur interne du gestionnaire d'erreur renvoie une exception pour éviter une boucle infinie.
Ce même gestionnaire d'erreur me sert pour logger les erreur PDO qui sont spécifiques à un traitement particulier.
Or, je m'aperçoit que mon gestionnaire d’événements, qui pourtant étend la classe Exception, ne peuple pas son attribut $message. J'avais bien entendu un constructeur qui appelait son constructeur parent.
Du coup pour palier au probleme, j'ai ajouté une méthode à mon gestionnaire d’événement mais du coup je suis quand même obligé d'utiliser un bloc try/catch pour récupérer les "erreurs", et c'est dans ce bloc catch que j'appelle ma méthode avec pour argument le message et le code rattrapés par le catch.
voila mon gestionnaire d'exceptions:
class myException extends Exception implements Input
{
private $Outputs=array();
private $_Error;
function __construct($str=NULL,$code=0)
{ parent::__construct($str, intval($code));
$this->getError();
}
function setMessage($str=NULL,$code=0)// methode pour peupler parent::message et parent::code "manuellement"
{ parent::__construct($str, intval($code));
$this->getError();
}
function addOutput(Output $obj)// ajout de module de sortie
{ if(!in_array($obj,$this->Outputs)) $this->Outputs[]=$obj;
return $this;
}
public function removeOutput(Output $obs)
{ if (is_int($key = array_search($obs, $this->Outputs, true))) unset($this->_Outputs[$key]);
return $this;
}
function getError()
{ if(count($this->Outputs)==0)
{ if(PHPDEBUG) $this->addOutput(new HtmlDisplay("div",'style="color:#C00"')); // HtmlDisplay est une classe qui envoie l'erreur en html
else $this->addOutput(new UserDisplay()); // UserDisplay est une sortie qui renvoie "un probleme est survenu sans autre details"
}
$this->_Error=array('erreur'=>$this->getCode(),'message'=>$this->getMessage(),'fichier'=>$this->getFile(),'ligne'=>$this->getLine());
$this->Display();
}
function getOutput(Output $obj)
{ try
{ if(in_array($obj,$this->Outputs)) return $this->_Error;
}
catch(Exception $e)
{ $_ENV['Exception']->setMessage($e->getMessage(),$e->getCode());
}
}
function Display()
{ foreach($this->Outputs as $Output)
{ $Output->run($this);
}
}
}
class testdisplay implements Output // une sortie simplette pour l'exemple
{ function run(Input $obj)
{ print_r($obj->getMessage($this));
}
}
$_ENV['exception']=new myException()
$_ENV['exception']->addOutput(new testdisplay());
set_exception_handler(array($_ENV['exception'],'getError'));
Les interfaces Input et Output servent juste à s'assurer que l'entrée de données trouve une sortie qui lui corresponde sans faute, mais ce qui m'importe n'est pas la sortie mais plutôt les entrées. La classe "testdisplay" n'est donc qu'un exemple simplifié.
à l'instanciation de l'objet $_ENV['Exception'] on se rend bien compte que rien n'est passé au constructeur. Du coup je ne m'etonne pas de ne rien y trouver.
Ce qui me gene, c'est l'ajout de "module" de sortie et l'appel à la méthode principale de l'objet "getError".
en effet, je ne peux pas ajouter de module de sortie à une classe, je dois passer par un objet déjà instancié. du coup je ne pense pas pouvoir utiliser de méthode statique pour ajouter ces modules.
pour l'instant, je suis obligé de faire comme suit:
try
{ echo $ma_variable_qui_nexiste_pas;
}
catch(Exception $e)
{ $_ENV['Exception']->addMessage($e->getMessage,$e->getCode());
}
Ça marche, mais c'est complétement ridicule. On attrape une exception pour en rebalancer une derrière. C'est comme de se payer une porsche mais de devoir la rejoindre à velo.
si je fais
set_exception_handler(array('myException','getError'));
j'obtiens un joli message d'erreur: Non-static method myException::getError() should not be called statically
Il faut aussi ajouter que ce gestionnaire d'exception ne peut pas être un singleton sachant que les exceptions venant du gestionnaire d'ERREUR et celles retournées par les erreurs PDO doivent être traitées différemment. ma classe PDO perso a un attribut publique statique étant une autre instance de myException.
Des idées? s'il vous faut d'autres précisions, je me ferai une joie d'y répondre