En effet, je pense qu'une exception, comme son nom l'indique, doit être exceptionnelle, et que de plus, une exception et une erreur ne s'adresse pas du tout aux mêmes entités.

Les exceptions ne devrait être misent en oeuvre que lorsqu'un événement qui n'est pas censé se produire survient lors de l'éxécution du code, comme par exemple l'impossibilité d'écrire sur le système de fichiers, de se connecter à une base de données, j'en passe et des meilleures, afin de permettre la mise en oeuvre d'une solution alternative permettant de contourner ou solutionner le problème rencontré, quitte à dégrader la qualité de service offerte par le code.

L'exception est effectivement le moyen le plus pratique et élégant pour pallier à l'indisponibilité de la base de données, en permettant de mettre en oeuvre une alternative de manière très simple au niveau du code, par exemple de la manière suivante :

<?php
...
try
{
$mysql->connect();
}
catch (databaseException $exception)
{
$logger->wrtie($exception->getMessage());
header('Status: 303');
header('Location: http://static.mondomaine.com');
}
...
?>

Cet exemple permet de se rendre compte que le code est le destinataire et le gestionnaire de l'exception, et non le développeur, qui n'a pas son mot à dire lorsque survient l'exception, même si c'est effectivement lui qui a décidé du comportement du code en cas d'exception lors de la phase de conception.

Pour résumé, les exceptions sont donc destinées à être mise en oeuvre lors de l'éxécution du code et leur gestion est assurée par ce dernier, au contraire des erreurs, qui doivent être à mon sens utilisées lors de la conception du code et qui sont à destination du développeur.

En effet, les erreurs doivent servir à avertir le programmeur qu'il n'utilise pas correctement une fonction ou une méthode, qu'elle soit native ou externe au langage, bref, qu'il n'utilise pas le code correctement.

Typiquement, j'utilise les erreurs de la manière suivante :

<?php
...
public function setWith(array $arguments)
{
if (array_key_exists(0, $arguments) === false)
{
trigger_error('Argument must be set at index 0', E_USER_ERROR);
}
else
{
$this->value = $arguments[0];
return parent::setWith($arguments);
}
}
...
?>

Dans ce cas, la cible de l'erreur est clairement le développeur, et c'est à lui, lors de la phase de conception et de test de son code, de prendre les mesures adéquates pour régler le problème, le code ne pouvant se corriger de lui-même.

Cependant, tout cela est sujet à discussion, et reléve énormément de la bataille de chapelle.

L'important, comme dans le cas des conventions de nommage, est de définir les cas d'utilisation respectifs des erreurs et des exceptions le plus tôt possible, de s'y tenir, et de communiquer largement à ce sujet, afin que tous les intervenants sur le code sachent précisement la solution à utiliser en fonction des différents cas de figure.

PHP apporte d'ailleurs à ce sujet son aide, et cela de manière native, en laissant clairement le choix au développeur d'utiliser l'une ou l'autre des philosophies.

La SPL implémente en effet un certain nombre d'exceptions dérivant du type de base Exception, séparée en deux familles distinctes :

  1. L'une, composée des dérivées de RuntimeException, est spécialement dédiée à la gestion des problèmes survenant lors de l'éxécution du code et il s'agit donc de celle qui a ma préférence.
  2. L'autre, composées des dérivées de LogicException, doit plus particulièrement être mise en oeuvre pour gérer les problèmes liés à la conception et la mise en oeuvre du code.

Cependant, comme à son habitude, PHP fait aussi de la merde n'importe quoi puisqu'il arrive souvent qu'il génére des erreurs là ou des exceptions seraient beaucoup plus appropriées.

Malheureusement, la sacro-sainte compatibilité avec les anciennes versions fait qu'il en sera toujours ainsi...

Et vous, vous utilisez les erreurs et les exceptions de quelle manière ?