Les exceptions ont évolué en tant que généralisation des erreurs. Le premier langage de programmation à inclure un mécanisme d’exception était Lisp au début des années 1970. Il y a un bon résumé dans A Pattern of Language Evolution de Gabriel et Steele. Les exceptions (qui n'étaient pas encore appelées exceptions) découlaient de la nécessité de spécifier le comportement d'un programme en cas d'erreur. Une possibilité consiste à arrêter le programme, mais ce n'est pas toujours utile. Les implémentations de Lisp avaient traditionnellement un moyen d'entrer dans le débogueur en cas d'erreur, mais les programmeurs voulaient parfois inclure la gestion des erreurs dans leur programme. Ainsi, les implémentations Lisp des années 1960 avaient un moyen de dire «faites ceci, et si une erreur se produit, faites-le plutôt». À l'origine, les erreurs provenaient de fonctions primitives, mais les programmeurs ont trouvé pratique de déclencher délibérément une erreur afin de sauter une partie du programme et d'accéder au gestionnaire d'erreurs.
En 1972, la forme moderne de gestion des exceptions dans Lisp est apparue dans MacLisp: throwet catch. Le groupe de préservation de logiciels répertorie de nombreux documents sur les premières implémentations de Lisp, y compris le manuel de référence MACLISP Révision 0 de David Moon . Les primitives catchet throwsont documentées au §5.3 p.43.
catchest la fonction LISP pour effectuer des sorties structurées non locales. (catch x)évalue xet renvoie ses valeurs, sauf que si, lors de l'évaluation, x (throw y)doit être évalué, catchretourne immédiatement ysans évaluation supplémentaire x.
catchpeut également être utilisé avec un argument econd, non évalué, utilisé comme étiquette pour distinguer les captures imbriquées. (…)
throwest utilisé avec catchcomme mécanisme de sortie non local structuré.
(throw x)évalue xet renvoie la valeur à la plus récente catch.
(throw x <tag>)renvoie la valeur de xretour à la plus récente catchétiquetée <tag>ou non étiquetée .
L'accent est mis sur le flux de contrôle non local . C'est une forme de goto (un goto ascendant), aussi appelé saut . La métaphore est que une partie du programme lance la valeur pour retourner au gestionnaire d'exceptions, et le gestionnaire d'exception prises cette valeur et retourne.
Aujourd'hui, la plupart des langages de programmation regroupent la balise et la valeur dans un objet exception et associent le mécanisme de capture à un mécanisme de traitement.
Les exceptions ne sont pas nécessairement des erreurs. Ils sont un moyen de sortir d'un bloc de code et des blocs environnants, en s'échappant jusqu'à ce qu'un gestionnaire pour l'exception soit atteint. Qu'une telle chose soit considérée comme une "erreur" au sens intuitif est subjectif.
Certaines langues font une distinction entre les termes «erreur» et «exception». Par exemple, certains dialectes Lisp doivent à la fois throwdéclencher une exception (flux de contrôle pour les utilisateurs, destiné à effectuer une sortie non locale d’une manière qui n’indique pas que quelque chose a mal tourné) et signalgénérer une erreur (ce qui indique que quelque chose a “mal tourné” et peut déclencher un événement de débogage).