# Programación en Ada/Excepciones

En Ada, cuando se produce algún error durante la ejecución de un programa, se eleva una excepción. Dicha excepción puede provocar la terminación abrupta del programa, pero se puede controlar y realizar las acciones pertinentes. También se pueden definir nuevas excepciones que indiquen distintos tipos de error.

## Excepciones predefinidas

En Ada, dentro del paquete Standard, existen unas excepciones predefinidas, éstas son:

### Constraint_Error

    cuando se intenta violar una restricción impuesta en una declaración, tal como indexar más allá de los límites de un array o asignar a una variable un valor fuera del rango de su subtipo.

### Program_Error

    se produce cuando se intenta violar la estructura de control, como cuando una función termina sin devolver un valor.

### Storage_Error

    es elevada cuando se requiere más memoria de la disponible.

### Tasking_Error

    cuando hay errores en la comunicación y manejo de tareas.

### Numeric_Error

    en Ada 83 se podía presentar cuando ocurría un error aritmético. A partir del estándar Ada 95, desaparece por motivos de portabilidad y pasa a ser un renombrado de Constraint_Error. Por ejemplo, en Ada 83 al dividir entre cero podía saltar Constraint_Error o Numeric_Error (dependiendo del compilador). En Ada 95 este error siempre levanta Constraint_Error.

### Name_Error

    se produce cuando se intenta abrir un fichero que no existe.

## Manejador de excepciones

Cuando se espere que pueda presentarse alguna excepción en parte del código del programa, se puede escribir un manejador de excepciones en las construcciones que lo permitan (bloques o cuerpos de subprogramas, paquetes o tareas), aunque siempre está el recurso de incluir un bloque en cualquier lugar del código.
Su sintaxis sería:
A la sentencia que comienza por when, se le denomina manejador de excepción.
La palabra reservada others indica cualquier otra excepción y debe ser la única y última opción. Por ejemplo, en un bloque:
En el momento en el que se produzca la elevación de Constraint_Error durante la ejecución de la secuencia de sentencias entre begin y exception, el flujo de control se interrumpe y se transfiere a la secuencia de sentencias que siguen a la palabra reservada => del manejador correspondiente.
Otro ejemplo con una función:
Nótese que no se puede devolver nunca el control a la unidad donde se elevó la excepción. Cuando se termina la secuencia de sentencias del manejador, termina también la ejecución de dicha unidad.
Si no se controla una excepción, ésta se propaga dinámicamente por las sucesivas unidades invocantes hasta que se maneje en otra o directamente termina la ejecución del programa proporcionando un mensaje con la excepción provocada por pantalla.

## Declaración y elevación de excepciones

Normalmente, es probable prever una situación de error que no se encuentra entre las excepciones predefinidas, por ello, se puede declarar excepciones. Por ejemplo:
Con lo que se puede elevar dicha excepción en el momento pertinente mediante la sentencia raise, cuya sintaxis es:
Por ejemplo, en un paquete de manejo de una pila estática de números enteros:
Obsérvese que no hace falta else en la sentencias if, pues al elevar la excepción, finaliza la ejecución del subprograma.
Ahora se podría escribir:
Si se quiere que dicha excepción no se propague más allá de la unidad en la que se elevó pero no se quiere manejar, se puede emplear una única sentencia vacía (null) dentro de su manejador correspondiente:
Aunque esto no evitaría que se terminara la ejecución de la unidad.
En el caso en el que se quiera propagar una excepción después de haber ejecutado las sentencias pertinentes, se incluiría una sentencia raise dentro del manejador:
En este caso se propaga otra excepción, pero podría haber sido la misma simplemente con raise, sin crear una nueva ocurrencia de la excepción, por ejemplo:
Así, se puede realizar un manejo de la excepción en varias capas, realizando sucesivas acciones en cada una de ellas. Dicha sentencia raise sin argumentos debe ser invocada directamente en el manejador, no es posible invocarla en un procedimiento llamado por el manejador.

## Información de la excepción

Ada proporciona información sobre una determinada excepción haciendo uso del paquete predefinido Ada.Exceptions y tras obtener la ocurrencia de la excepción mediante esta notación:

## Manual de referencia de Ada

* Section 11: Exceptions

## Enlaces externos

* Excepciones: artículo de la Universidad de Valladolid. Ejemplos en Ada y Eiffel.