Las excepciones evolucionaron como una generalización de errores. El primer lenguaje de programación que incluyó un mecanismo de excepción fue Lisp a principios de la década de 1970. Hay un buen resumen en A Pattern of Language Evolution por Gabriel y Steele. Las excepciones (que aún no se llamaron excepciones) surgieron de la necesidad de especificar el comportamiento de un programa si se produce un error. Una posibilidad es detener el programa, pero esto no siempre es útil. Las implementaciones de Lisp tradicionalmente han tenido una forma de ingresar el depurador en un error, pero a veces los programadores querían incluir el manejo de errores en su programa. Entonces, las implementaciones de Lisp en la década de 1960 tenían una forma de decir "haz esto, y si ocurre un error, hazlo en su lugar". Originalmente, los errores provenían de funciones primitivas, pero los programadores consideraron conveniente activar deliberadamente un error para omitir alguna parte del programa y saltar al controlador de errores.
En 1972, la forma moderna de manejo de excepciones en Lisp apareció en MacLisp: throwy catch. El Grupo de preservación de software enumera una gran cantidad de material sobre las primeras implementaciones de Lisp, incluida la Revisión 0 del Manual de referencia MACLISP de David Moon . Las primitivas catchy throwse documentan en §5.3 p.43.
catches la función LISP para hacer salidas estructuradas no locales. (catch x)evalúa xy devuelve sus valores, excepto que si durante la evaluación de x (throw y)debe evaluarse, catchdevuelve inmediatamente ysin más evaluaciones x.
catchtambién se puede usar con un argumento econd, no evaluado, que se usa como etiqueta para distinguir entre capturas anidadas. (...)
throwse utiliza con catchun mecanismo estructurado de salida no local.
(throw x)evalúa xy devuelve el valor al más reciente catch.
(throw x <tag>)arroja el valor de xnuevo al más reciente catchetiquetado con <tag>o sin etiquetar.
El foco está en el flujo de control no local . Es una forma de goto (un goto solo hacia arriba), que también se llama salto . La metáfora es que una parte del programa arroja el valor para volver al controlador de excepciones, y el controlador de excepciones captura ese valor y lo devuelve.
La mayoría de los lenguajes de programación hoy empacan la etiqueta y el valor en un objeto de excepción, y combinan el mecanismo de captura con un mecanismo de manejo.
Las excepciones no son necesariamente errores. Son una forma de salir de un bloque de código y de los bloques circundantes, escapando hasta que se alcanza un controlador para la excepción. Si tal cosa se considera un "error" en el sentido intuitivo es subjetivo.
Algunos idiomas hacen una distinción entre los términos "error" y "excepción". Por ejemplo, algunos dialectos de Lisp tienen throwque generar una excepción (flujo de control para los usuarios, destinado a realizar una salida no local de una manera que no indica que algo salió "mal") y signalgenerar un error (que indica que algo salió "mal" y puede desencadenar un evento de depuración).