Je me demande dans quelle mesure je dois m'efforcer de forcer l'obtention d'informations de débogage utiles lors de la création de messages d'exception, ou dois-je simplement faire confiance à l'utilisateur pour fournir les bonnes informations, ou encore confier la collecte d'informations à un gestionnaire d'exception ?
Je vois beaucoup de gens qui font leurs exceptions comme :
throw new RuntimeException('MyObject is not an array')
ou d'étendre les exceptions par défaut avec des exceptions personnalisées qui ne font pas grand-chose à part changer le nom de l'exception :
throw new WrongTypeException('MyObject is not an array')
Mais cela ne fournit pas beaucoup d'informations de débogage... et n'impose aucune forme de formatage du message d'erreur. Vous pouvez donc vous retrouver avec exactement la même erreur produisant deux messages d'erreur différents... par exemple "Database connection failed" ou "Could not connect to db".
Bien sûr, s'il s'agit d'une bulle, il affichera la trace de la pile, ce qui est utile, mais cela ne me dit pas toujours tout ce que j'ai besoin de savoir et je finis généralement par devoir lancer des instructions var_dump() pour découvrir ce qui s'est mal passé et où... bien que cela puisse être quelque peu compensé par un gestionnaire d'exception décent.
Je commence à penser à quelque chose comme le code ci-dessous, où je exiger le lanceur de l'exception doit fournir les arguments nécessaires pour produire le message d'erreur correct. Je pense que cela pourrait être la voie à suivre dans ce cas :
- Un niveau minimum d'informations utiles doit être fourni
- Produit des messages d'erreur assez cohérents
- Les modèles de messages d'exception se trouvent tous au même endroit (classes d'exception), ce qui facilite la mise à jour des messages...
Mais je vois l'inconvénient d'être plus difficile à utiliser (il faut chercher la définition de l'exception), et donc de décourager les autres programmeurs d'utiliser les exceptions fournies...
J'aimerais avoir des commentaires sur cette idée et sur les meilleures pratiques pour un cadre cohérent et flexible de messages d'exception.
/**
* @package MyExceptions
* MyWrongTypeException occurs when an object or
* datastructure is of the incorrect datatype.
* Program defensively!
* @param $objectName string name of object, eg "\$myObject"
* @param $object object object of the wrong type
* @param $expect string expected type of object eg 'integer'
* @param $message any additional human readable info.
* @param $code error code.
* @return Informative exception error message.
* @author secoif
*/
class MyWrongTypeException extends RuntimeException {
public function __construct($objectName, $object, $expected, $message = '', $code = 0) {
$receivedType = gettype($object)
$message = "Wrong Type: $objectName. Expected $expected, received $receivedType";
debug_dump($message, $object);
return parent::__construct($message, $code);
}
}
....
/**
* If we are in debug mode, append the var_dump of $object to $message
*/
function debug_dump(&$message, &$object) {
if (App::get_mode() == 'debug') {
ob_start();
var_dump($object);
$message = $message . "Debug Info: " . ob_get_clean();
}
}
Puis utilisé comme :
// Hypothetical, supposed to return an array of user objects
$users = get_users(); // but instead returns the string 'bad'
// Ideally the $users model object would provide a validate() but for the sake
// of the example
if (is_array($users)) {
throw new MyWrongTypeException('$users', $users, 'array')
// returns
//"Wrong Type: $users. Expected array, received string
}
et nous pourrions faire quelque chose comme un nl2br dans un gestionnaire d'exception personnalisé pour rendre les choses agréables pour la sortie html.
Je lisais : http://msdn.microsoft.com/en-us/library/cc511859.aspx#
Et il n'y a aucune mention de quelque chose comme ça, donc peut-être que c'est une mauvaise idée...
1 votes
Je suis sûr que le constructeur ici devrait correspondre à
RuntimeException::__construct()