Manejo de Errores
Gratuita—Año 2015—Edición Abril.
Equipo PHP: Ileanne Leal Marycarmen Ramos
.
Equipo Editorial [Director Editorial] Marycarmen Ramos
marycarmenr893@gmail.com
[Director de Arte] Ileanne Leal ileanne.leal@gmail.com
[Maquetacion] Ileanne Leal
Editorial
ileanne.leal@gmail.com
[Documentacion] Marycarmen Ramos
Manejo de Errores
marycarmenr893@gmail.com
[Universidad]
Esta edición es realizada especialmente para el conocimiento sobre manejo de errores y sus excepciones. Primeramente, antes de entrar en el tema de las excepciones en programación, se ha de matizar en el concepto de qué son las excepciones, vistas desde un punto de vista fuera y dentro del mundo de la programación.
Universidad de Oriente— Monagas
Contenido Artículo interno ......................... 2 Artículo interno ......................... 2 Artículo interno ......................... 3
En el lenguaje humano, una excepción es un elemento excluyente de una regla, y de forma convencional se ha extendido esta definición. En el lenguaje máquina, una excepción se trata, de forma general, de algo que no se espera que ocurra, pero que puede ocurrir, similar al tratamiento de errores, pero de los errores en tiempo de ejecución. A veces estas excepciones, para una máquina, no son casos que no deberían estar contemplados, tal y como un programador se lo asigna, sino que pueden ser indicadores para comprobar que realmente todo está marchando bien o no.
Los Editores
Artículo interno ......................... 3 Artículo interno ......................... 4 Artículo interno ......................... 4 Artículo interno ......................... 4
Introduccion Las excepciones son en realidad errores durante la ejecución. Si uno de esos errores se produce y no implementamos el manejo de excepciones, el programa sencillamente terminará abruptamente. Es muy probable que si hay ficheros abiertos no se guarde el contenido de los buffers, ni se cierren, además ciertos objetos no serán destruidos, y se producirán fugas de memoria.
En programas pequeños podemos prever las situaciones en que se pueden producir excepciones y evitarlos. Las excepciones más habituales son las de peticiones de memoria fallidas.
“En los programas de ordenador hechos en C existió durante mucho tiempo la costumbre de usar el comando "goto" (también implementada en C++), pero éste se ha ido eliminando progresivamente de casi todos y cada uno de los códigos y programas que han ido surgiendo
Manejo de Errores Habitualmente cuando un programador hace algo, tal como llamar a una función, puede evaluar la validez del resultado devuelto por dicha función. Por ejemplo, si intentamos abrir un archivo que no existe, el resultado devuelto podría ser nulo. Hay dos estrategias comunes para manejar este tipo de situaciones: 1. Incluir el código del error en el resultado de la fun-
ción, o 2. utilizar una variable global con el estatus del error. En ambos casos, el programador debe revisar si ha ocurrido un error, y en ese caso predecir una acción apropiada que lo maneje
3
Algoritmo con errores y excepciones
Manejo de errores de un programa
Tipos de errores Errores de sintaxis Estos errores son seguramente los más simples de resolver, pues son detectados por el intérprete (o por el compilador, según el tipo de lenguaje que estemos utilizando) al procesar el código fuente y generalmente son consecuencia de equivocaciones al escribir el programa. En el caso de Python estos errores son indicados con un mensajeSyntaxError. Por ejemplo, si trabajando con Python intentamos definir una función y en lugar dedef escribimos dev. (Librosweb, 2010) Errores semánticos Se dan cuando un programa, a pesar de no generar mensajes de error, no produce el resultado esperado. Esto puede deberse, por ejemplo, a un algoritmo incorrecto o a la omisión de una sentencia. (Librosweb, 2010) Errores de ejecución Estos errores aparecen durante la ejecución del programa y su origen puede ser diverso. En ocasiones pueden producirse por un uso incorrecto del programa por parte del usuario, por ejemplo si el usuario ingresa una cadena cuando se espera un número. En otras ocasiones pueden deberse a errores de programación, por ejemplo si una función intenta acceder a la quinta posición de una lista de 3 elementos o realizar una división por cero. Una causa común de errores de ejecución que generalmente excede al programador y al usuario, son los recursos externos al programa, por ejemplo si el programa intenta leer un archivo y el mismo se encuentra dañado. (Librosweb, 2010)
4
Universidad de Oriente. Núcleo Monagas. Campus Juanico (Urbanización Juanico—Maturín—Edo Monagas) Tlf (0291) 6415402 / Cel (0424) 9180968 Correos (cisco.monagas@gmail.com) - (cisco.monagas@udo.edu.ve) 5
Excepciones
Excepciones Excepciones Los errores de ejecución son llamados comúnmente excepciones y por eso de ahora en más utilizaremos ese nombre. Durante la ejecución de un programa, si dentro de una función surge una excepción y la función no la maneja, la excepción se propaga hacia la función que la invocó, si esta otra tampoco la maneja, la excepción continua propagándose hasta llegar a la función inicial del programa y si esta tampoco la maneja se interrumpe la ejecución del programa. Veamos entonces como manejar excepciones. (Librosweb, 2010) Manejo de excepciones Para el manejo de excepciones los lenguajes proveen ciertas palabras reservadas, que nos permiten manejar las excepciones que puedan surgir y tomar acciones de recuperación para evitar la interrupción del programa o, al menos, para realizar algunas acciones adicionales antes de interrumpir el programa. (Librosweb, 2010) 6
Conformacion de los bloques try y catch Por norma general, los comandos try y catch conforman bloques de código. Cada uno de estos bloques se recomienda, aunque sea de una única línea, envolverlos en llaves, como muestra el siguiente ejemplo: // ...código previo... try { // bloque de código a comprobar } catch( tipo ) // Ha ocurrido un suceso en el try que se ha terminado //la ejecución del bloque y catch recoge y analiza lo sucedido { // bloque de código que analiza lo que ha lanzado el try } // ...código posterior…
Generalmente entre el try y el catch no se suele insertar código, pero se insta al lector a que lo intente con su compilador habitual y que compruebe si hay errores o no de compilación.
7
Control de Excepciones Una excepción es un error que puede ocurrir debido a una mala entrada por parte del usuario, un mal funcionamiento en el hardware, un argumento inválido para un cálculo matemático, etc. Para remediar esto, el programador debe estar atento y escribir los algoritmos necesarios para evitar a toda costa que un error de excepción pueda hacer que el programa se interrumpa de manera inesperada. C++ soporta una forma más directa y fácil de ver tanto para el programador como para los revisores del código en el manejo de excepciones que su símil en el C estándar y esta consiste, tratándose del lenguaje C++, en el mecanismo try, throw ycatch. La lógica del mecanismo mencionado consiste en: Dentro de un bloque try se pretende evaluar una o más expresiones y si dentro de dicho bloque se produce un algo que no se espera se lanza por medio de throw una excepción, la misma que deberá ser capturada por un catch específico. Puesto que desde un bloque try pueden ser lanzados diferentes tipos de errores de excepción es que puede haber más de un catch para capturar a cada uno de los mismos. Si desde un try se lanza una excepción y no existe el mecanismo catch para tratar dicha excepción el programa se interumpirá abruptamente despues de haber pasado por todos los catchs que se hayan definido y de no haber encontrado el adecuado. Los tipos de excepciones lazados pueden ser de un tipo primitivo tal como: int, float, char, etc. aunque normalmente las exepciones son lanzadas por alguna clase escrita por el usuario o por una clase de las que vienen incluidas con el compilador. En el programa que se listará a continuación muestra un ejemplo de como lanzar una excepción de tipo int dentro del bloque try, y cómo capturar la excepción por medio de catch. Ejemplo: // Demostración de los comandos try, throw y catch #include <iostream> // Función: main // Recibe: void // Devuelve: int // En la función principal se tratarán los comandos try, throw y catch int main(void) { try // Se intenta hacer el siguiente código { // Aquí puede ir más código... throw 125; //...aunque directamente en este caso se lanza una excepción. } catch(int) // Se captura con un catch de enteros (podría usarse long o char, por ejemplo) { std::cout << "Ha surgido una excepción de tipo entero" << std::endl; // y se muestra por pantalla }
8
Excepciones genericas Como ya se ha mencionado, los errores pueden deberse a una multitud de situaciones muchas veces inesperadas, por tal motivo, en C++ existe una forma de manejar excepciones desconocidas ( genéricas ) y es buena idea que si se está escribiendo un controlador de excepciones incluya un catch para capturar excepciones inesperadas. Por ejemplo, en el siguiente programa se escribe un catch que tratará de capturar cualquier excepción inesperada. // Demostración: try, throw y catch #include <iostream> using namespace std; int main() { try { throw 125; } catch(...) { cout << "Ha ocurrido un error inesperado..." << endl; } cin.get(); return 0; }
9
Excepciones de Clases Si usted está usando una clase escrita por terceras personas o de las que se incluyen con el compilador y desea utilizar el mecanismo try, deberá conocer el tipo de excepción lanzado por dicha clase para así poder escribir el catch correspondiente para el tratamiento de dicho error. Por ejemplo, la función at() de la clase string( que será estudiada más adelante ) lanza una excepción cuando se trata de leer o escribir un componente fuera de rango. En tales casos usted puede proceder a capturar el error como se muestra en el siguiente programa. / Compilado y probado exitosamente con Dev-C++ // Demostración: excepción de la clase string #include <iostream> #include <string> using namespace std; int main() { string s = "Hola"; try { cout << s.at(100) << endl; } catch(exception& e) { cout << e.what() << endl; } cin.get(); return 0; }
10
Excepciones genericas Tal como se mostró en el programa anterior, los errorres generados por las librerías estándar de C++ pueden ser capturados por un catch que tome un parámetro tipo exception. Realmente, exception es una clase base de donde usted puede derivar las suyas y sobrescribir los métodos para el tratamiento de excepciones. La clase exception está incluida en la libreria <exception> y su estructura es la siguiente: class exception { public: exception() throw() { } virtual ~exception() throw(); virtual const char* what() const throw(); };
En muchos casos bastará con sobrescribir el método what() en la clase derivada de exception, ya que dicho método es el encargado de generar el mensaje que trata de explicar la naturaleza del error ocurrido. En el programa que veremos en seguida, se da un ejemplo sencillo de cómo crear una clase derivada de la clase exception con el objetivo de sobrescribir el método what(). // Demostración: sobrescritura del método what() #include <iostream> #include <cstdlib> #include <exception> using namespace std; class div_cero : public exception { public: const char* what() const throw() { return "Error: división por cero..."; } }; int main(int argc, char *argv[]) { double N, D; cout << "Probando división" << endl; cout << "Ingrese el numerador :"; cin >> N; cin.clear();
11
Excepciones de genericas Siguiendo la misma metodología mostrada por el programa anterior, usted puede crear clases independientes para capturar errores de excepciones específicas. Por ejemplo, si se desea crear una serie de funciones matemáticas se deben considerar los sucesos de errores tales como: División por cero, Error de dominio, Error de rango, etc. Así, el siguiente programa puede ser un buen ejemplo para que usted escriba sus propios controladores de mensajes de error. Observe cómo en el programa se crea la clase ErrorMat y dentro de la misma la función porque() la cual se encargará de desplegar el mensaje de error. Aunque ErrorMat solo ha sido pensada para tratar los posibles errores de rango y errores de dominio, la misma puede rescribirse para capturar todos los errores posibles que puedan resultar a raiz de operaciones matemáticas. Nota: No deje de observar también, cómo la función independiente logaritmo() verifica si el parámetro pasado a la misma es 0 o menor que 0 y en tales circunstancias se lanzaría (throw) un error de excepción del tipo ErrorMat ya que el dominio para la función log() es el de los números positivos y el logaritmo de cero no está definido en los números reales
// Demostración: try, throw y catch #include <iostream> #include <cmath> using namespace std; static const int EDOMINIO=100; static const int ERANGO=101; class ErrorMat { public: ErrorMat() : motivo(0) {}; ErrorMat(int m) : motivo(m) {}; const char* porque() const throw(); private: int motivo; }; const char* ErrorMat::porque() const throw() { switch (motivo) { case EDOMINIO: return "Error de Dominio ";break; case ERANGO: return "Error de Rango ";break; default: return "Error Desconocido"; //En rigor no debería ocurrir } } double logaritmo(const double n) { try { if (n < 0) throw(ErrorMat(EDOMINIO) ); if (n == 0) throw(ErrorMat(ERANGO) ); return log(n); }
12
Excepciones genericas Tal como se mostró en el programa anterior, los errorres generados por las librerías estándar de C++ pueden ser capturados por un catch que tome un parámetro tipo exception. Realmente, exception es una clase base de donde usted puede derivar las suyas y sobrescribir los métodos para el tratamiento de excepciones. La clase exception está incluida en la libreria <exception> y su estructura es la siguiente: class exception { public: exception() throw() { } virtual ~exception() throw(); virtual const char* what() const throw(); };
En muchos casos bastará con sobrescribir el método what() en la clase derivada de exception, ya que dicho método es el encargado de generar el mensaje que trata de explicar la naturaleza del error ocurrido. En el programa que veremos en seguida, se da un ejemplo sencillo de cómo crear una clase derivada de la clase exception con el objetivo de sobrescribir el método what(). // Demostración: sobrescritura del método what() #include <iostream> #include <cstdlib> #include <exception> using namespace std; class div_cero : public exception { public: const char* what() const throw() { return "Error: división por cero..."; } }; int main(int argc, char *argv[]) { double N, D; cout << "Probando división" << endl; cout << "Ingrese el numerador :"; cin >> N; cin.clear();
13
Conclusiones Se conocen por errores aquellos problemas que ocurren durante la ejecución de un programa y de estos es evaluar el resultado devuelto por la función que llamo, y así dar un mensaje ejecutando un fragmento de código que resuelve la situación, entre uno de los casos puede enviar un mensaje diciendo error o enviando un valor por defecto y a las excepciones por ser las condiciones que salen del flujo normal, cuando se genera una excepción es importante actuar en consecuencia, ya sea mostrando un mensaje de error, guardándolo en un archivo, o modificando el resultado final de la función. Cuando no es posible utilizar un dato dentro de una porción de código, es importante informar el problema al código invocante, ya sea mediante una excepción o mediante un valor de retorno especial, donde el sistema fuerza un salto hacia el bloque de excepciones más cercano del código en el cual se toman las acciones apropiadas tendientes a solucionar o alertar acerca del error producido.
14
Referencias Bibliograficas Contenido extraído de: http://es.wikibooks.org/wiki/ Programaci%C3%B3n_en_C%2B%2B/Excepciones. Consultado el día 12 de Abril de 2015 Contenido extraído de: http://c.conclase.net/curso/?cap=043. Consultado el día 12 de Abril de 2015