viernes, 18 de mayo de 2012

Try...Catch...Finally


Manipulación de errores
Try…Catch…Finally


Visual Basic admite un control de excepciones (errores) tanto estructurado como no estructurado.
El control de errores estructurado y no estructurado permite establecer un plan para detectar posibles errores, y así impedir que éstos interfieran en los supuestos objetivos de la aplicación.
Si se produce una excepción en un método que no esté preparado para controlarla, la excepción se propagará de vuelta al método de llamada o al método anterior. Si el método anterior tampoco tiene controlador de excepciones, la excepción se propagará de vuelta al llamador del método, y así sucesivamente. La búsqueda de un controlador continuará hasta la pila de llamadas, que es la serie de procedimientos a los que se llama dentro de la aplicación. Si ésta tampoco encuentra un controlador para la excepción, se mostrará un mensaje de error y la aplicación finalizará.


Podemos clasificar los tipos de errores en una serie de categoría genérica.

1.      Errores de escritura: son los de localización más inmediata, ya que se produce con un error sintáctico al escribir nuestro código, y gracias al IDE de visual Studio .NET, podemos detectarlos rápidamente. Cuando escribimos una sentencia incorrectamente, dejamos algún paréntesis sin cerrar, etc., el IDE subraya la parte del código  errónea, y nos muestra un mensaje informativo del error al situar el cursor del ratón sobre el mismo.



2.      Errores de ejecución: este tipo de errores son los que provocan un fallo en la ejecución del programa y su interrupción. No obstante, si utilizamos los gestores de error que proporcionan la herramienta de desarrollo correspondiente, podremos en algunos casos, evitar la cancelación de la ejecución, recuperando su control. El ejemplo siguiente provoca un error, ya que intenta asignar un valor que no corresponde al tipo de una variable.



“txtCantidad” es un valor numérico, por lo tanto la línea de código debe ir escrita como la de “txtPrecio”.

3.      Errores lógicos: estos errores son de los de más difícil captura, ya que el código se encuentra correctamente escrito, produciéndose el problema por un fallo de planteamiento de código.

Ejemplo: el control de un programa no entra en un bucle porque una variable no ha tomado determinado valor; el flujo del  programa sale antes de lo previsto de un procedimiento, al evaluar una expresión que esperábamos que tuviera un resultado diferente, etc.

Dentro del esquema de gestión de errores del entorno .NET Framework, encontramos las figuras del error y la excepción.

  •  Error: un error es un evento que se produce durante el funcionamiento de un programa, provocando una interrupción en su flujo de ejecución. Al producirse esta situación, el error genera un objeto excepción.
  •    Excepción: una excepción es un objeto generado por un error, que contiene información sobre las características del error que se ha producido.VB.NET proporciona dos tipos de tratamiento de error: estructurado y no estructurado. El primero se basa en los esquemas de captura de errores de lenguajes como C# y C++; gestionando los errores a través de excepciones, y una estructura de control que se encarga de atrapar aquellas excepciones que se produzcan. El segundo es un sistema heredado de versiones anteriores de VB, y está basado en la detección y captura de errores a través de etiquetas de código, mediante saltos no estructurados en el flujo de la ejecución, nos enfocaremos únicamente en los errores estructurados

.
Manipulación de estructuras de errores
En este tipo de tratamiento, cada vez que se produce un error, se genera un objeto de la clase Exception, conteniendo la información del error ocurrido. La manera de capturar este tipo de objetos pasa por utilizar una estructura de control de lenguaje, proporcionada para esta finalidad.


La Clase Exception
Cada vez que se produce un error, el entorno de ejecución genera una excepción con la información del error acontecido. Para facilitarnos la tarea de manipulación de la excepción producida, en un controlador de excepciones obtenemos un objeto de la clase excepción, de forma que, a través de sus miembros, podemos saber que ha pasado.
Entre las siguientes propiedades y métodos que podemos utilizar, se encuentran los siguientes:

Message: descripción del error
Source: nombre del objeto o aplicación que ocasiono el error
StackTrace: ruta o traza del código en la que se produjo el error
ToString (): devuelve una cadena con información detallada del error. En esta cadena podemos encontrar también, los valores obtenidos de las propiedades anteriores; por lo que el uso de este método, en muchas ocasiones será el modo más recomendable para obtener los datos de la excepción.   

Control estructurado de excepciones
En el control estructurado de excepciones, los bloques de código se encapsulan y cada uno de ellos tiene uno o varios controladores asociados. Cada controlador especifica una forma de condición de filtro para el tipo de excepción que controla. Cuando el código de un bloque protegido genera una excepción, se busca por orden en el conjunto de controladores correspondientes y se ejecuta el primero que contenga una condición de filtro coincidente. Un método puede tener varios bloques de control estructurado de excepciones y dichos bloques pueden además estar anidados.
La instrucción Try...Catch...Finally se utiliza específicamente para el control estructurado de excepciones.

El uso de la instrucción Try…Catch…Finally permite proteger bloques de código con posibilidades de generar errores. Los controladores de excepciones pueden anidarse, y las variables que se declaren en cada bloque tendrán un ámbito local.
Ejemplo:

Try
‘El código que puede producir el error
Catch [filtros opcionales o tipos de errores a capturar]
‘Código para cuando se produzca un error
 [bloques catch adicionales]
Finally
‘Código para cuando aparezca o no un error
End Try

El bloque Try de un controlador de excepción Try...Catch...Finally contiene la sección del código que el controlador de errores va a supervisar. Si se produce un error durante la ejecución de cualquier parte del código de esta sección, Visual Basic examinará cada instrucción Catch de Try...Catch...Finally hasta que encuentre una cuya condición coincida con el error. Si la encuentra, el control se transferirá a la primera línea de código del bloque Catch. Si no se encuentra una instrucción Catch coincidente, la búsqueda continuará en las instrucciones Catch del bloque Try...Catch...Finally exterior que contiene el bloque en el que ocurrió la excepción. Este proceso se prolongará a lo largo de toda la pila hasta que se encuentre un bloque Catch coincidente en el procedimiento actual. De no encontrarse, se produciría un error.
El código de la sección Finally siempre se ejecuta en último lugar, inmediatamente antes que el bloque de control de errores pierda su ámbito, con independencia de que se ejecute el código de los bloques Catch. Sitúe el código de limpieza (el código que cierra los archivos y libera los objetos, por ejemplo) en la sección Finally.
Filtrar errores en el bloque Catch
Los bloques Catch ofrecen tres opciones para filtrar errores específicos. En una de ellas, los errores se filtran basándose en la clase de la excepción (en este casoClassLoadException), como se muestra en el siguiente código:

Try  
   ' "Try" block.
Catch e as ClassLoadException  
   ' "Catch" block.
Finally  
   ' "Finally" block.
End Try

Si se produce un error ClassLoadException, se ejecuta el código del bloque Catch especificado.
En la segunda opción para filtrar errores, la sección Catch puede filtrar cualquier expresión condicional. Un uso común de este formato del filtro Catch consiste en comprobar números de error específicos, como se muestra en el código siguiente:

Try
   ' "Try" block.
Catch When ErrNum = 5 'Type mismatch.
   ' "Catch" block.
Finally
   ' "Finally" block.
End Try

Cuando Visual Basic encuentra el controlador de errores coincidente, ejecuta el código de este controlador y pasa el control al bloque Finally.
El bloque Finally siempre se ejecuta, con independencia de cualquier otra acción que tenga lugar en los bloques Catch anteriores. No puede utilizar Resume o Resume Next en el control estructurado de excepciones.

Ahora se realizarán una serie de ejemplos que aclararán lo expuesto


Module Module1

    Sub Main()
        Dim sValor As String
        Dim iNumero As Integer
        Try
            'Aqui comienza el control de errores
            Console.WriteLine("Introducir un número")
            sValor = Console.ReadLine
            'Si no hemos introducido ningún número
            iNumero = sValor 'aquí se producira un error

        Catch
            'Si se produce un error, se generará una excepción
            'que capturamos en este bloque de código
            'manipulador de excepción, definido por Catch
            Console.WriteLine("Error al introducir el número" & ControlChars.CrLf & "el valor {0} es incorrecto", sValor)
        End Try
        Console.Read()
    End Sub

End Module

Esta y las siguientes 2 líneas no pertenecen al código anterior
Observen que antes de module1 no están declaradas Option Explicit On o
Option Strict On.







1.      Private Sub Form1_Load(ByVal sender As System.Object, _  
2.                     ByVal e As System.EventArgs) _  
3.                             Handles MyBase.Load  
4.        
5.          Try  
6.        
7.              Dim ContadorDeArchivos As System.Collections.ObjectModel.ReadOnlyCollection(Of String)  
8.              'le indicamos el path que queremos  
9.              ContadorDeArchivos = My.Computer.FileSystem.GetFiles("C:\WINDOWS")  
10.          'nos devuelve la cantidad de archivos  
11.    
12.          MsgBox("La Cantidad de Archivos es: " & CStr(ContadorDeArchivos.Count))  
13.          ' error  
14.      Catch oExcep As Exception  
15.          MsgBox("Descripción del error : " & _  
16.                 oExcep.Message, MsgBoxStyle.Critical, "Error")  
17.      End Try  
18.    
19.  End Sub   




ejemplo:
este ejemplo es de una barra que carga, pero al sobrepasar su valor de 100, osea al 101, aparece un error

Public Class Form1

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        Try
            ProgressBar1.Value = ProgressBar1.Value + 1
        Catch ex As Exception
            Timer1.Enabled = False
            MsgBox("El valor de '101' no es valido para 'value'. value deberia estar entre 'Minimun' y 'Maximun'. Nombre del parametro: 'Value'")
            MsgBox("La barra de progreso ha alcanzado su limite maximo, verifique el codigo y trate de no sobrepasar el valor de 'Maximun'", MsgBoxStyle.Information, "Error")
            MsgBox("Al producirse el error la propiedad Enable del Timer cambia a False", MsgBoxStyle.Information, "Error")
        End Try
    End Sub


Ojala la información de este blog les haya sido útil, muchas gracias.

No hay comentarios:

Publicar un comentario