Información general sobre el control estructurado de excepciones de Visual Basic

Visual Basic admite el control estructurado de excepciones, que puede utilizar para crear y mantener programas mediante controladores de errores consistentes y exhaustivos. El control estructurado de excepciones es un código diseñado para detectar y dar respuesta a los errores que se producen durante la ejecución, mediante la combinación de una estructura de control (similar a Select Case o While) con excepciones, bloques de código protegidos y filtros.

Con la instrucción Try...Catch...Finally, puede proteger bloques de código que tienen posibilidades de producir errores. Los controladores de excepciones pueden anidarse, y las variables que se declaren en cada bloque tendrán un ámbito local.

vínculo a vídeo Dispone de una demostración en vídeo relacionada, vea Cómo: Excepciones no Controladas de correo electrónico?.

Instrucción Try...Catch...Finally

El código siguiente muestra la estructura de la instrucción Try...Catch...Finally.

Try
    ' Starts a structured exception handler.
    ' Place executable statements that may generate 
    ' an exception in this block.
Catch '[optional filters]
    ' This code runs if the statements listed in 
    ' the Try block fail and the filter on the Catch statement is true.
'[Additional Catch blocks]
Finally
    ' This code always runs immediately before
    ' the Try statement exits.
End Try
' Ends a structured exception handler.

El bloque Try de un controlador de excepciones Try...Catch...Finally contiene la sección de código que se va a controlar para las excepciones. Si aparece un error durante la ejecución de esta sección, Visual Basic examina cada instrucción Catch dentro de Try...Catch...Finally hasta que encuentra una con una condición que 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 de 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. Si no necesita detectar las excepciones, pero debe limpiar los recursos, considere el uso de la instrucción Using en lugar de una sección Finally. Para obtener más información, vea Using (Instrucción, Visual Basic).

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 caso ClassLoadException), 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 tipo de 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.

Nota

Al buscar un bloque Catch que controle una excepción, se evalúa el controlador de cada bloque hasta encontrar uno que coincida. Puesto que estos controladores pueden ser llamadas a funciones, es posible que se produzcan efectos secundarios no esperados; por ejemplo, una llamada de este tipo puede cambiar una variable pública y provocar que ésta se utilice en el código de un bloque Catch distinto que termina controlando la excepción.

La tercera alternativa consiste en combinar las dos primeras opciones y utilizar ambas para el control de excepciones. Las instrucciones Catch deben ir de lo más específico a lo menos específico. Un bloque Catch por sí mismo detectará todas las excepciones derivadas de Exceptiony, por consiguiente, siempre debe ser el último bloque antes de Finally.

Bifurcación fuera de bloques Try…Catch

Es posible bifurcar a partir de un bloque Catch de nuevo en la instrucción Try inicial o la instrucción End Try, pero no es posible bifurcar en un bloque Try…Catch de inclusión. Esto se muestra aquí:

Bifurcación Try Catch

Ejemplo de controlador estructurado de excepciones

En el siguiente ejemplo se muestra otro controlador de errores sencillo que utiliza la instrucción Try...Catch...Finally.

Option Strict On
Imports System.IO

Module Module1
    Private Const FileName As String = "TestFile.data"

    Public Sub Main()

        ' First, create a new data file and write some data to the file.
        ' 1. Create the new, empty data file.
        If File.Exists(FileName) Then
            File.Delete(FileName)
        End If
        Dim fs As New FileStream(FileName, FileMode.CreateNew)

        ' 2. Create a BinaryWriter object for the data.
        Dim writer As New BinaryWriter(fs)

        ' 3. Write some sample data to the file.
        For i = 0 To 10
            writer.Write(i)
        Next i
        writer.Close()
        fs.Close()

        ' Now read from the file you just made.
        ' 1. Create a BinaryReader object for the data stream.
        fs = New FileStream(FileName, FileMode.Open, FileAccess.Read)
        Dim reader As New BinaryReader(fs)

        ' 2. Read data from TestFile.data. The loop terminates with an
        ' EndOfStreamException when an attempt is made to read past
        ' the end of the stream.
        Try
            ' This loop terminates with an EndOfStreamException when it 
            ' reaches the end of the stream.
            While True
                Console.WriteLine(reader.ReadInt32())
            End While
            Console.WriteLine("The data was read with no error.")
        ' 3. Report the first error that is caught, if there is one.
        Catch eosExcep As EndOfStreamException
            ' This Catch block is executed when the reader attempts
            ' to read past the end of the stream.
            Console.WriteLine("End-of-stream exception occurred.")
        Catch IOExcep As System.IO.IOException
            ' For this Catch block, some other error occurred before
            ' the end of stream was reached. Print the standard
            ' exception message.
            Console.WriteLine(IOExcep.Message)
        Finally
            ' The Finally block is always executed.
            Console.WriteLine("Executing the Finally block.")
            reader.Close()
            fs.Close()
        End Try
    End Sub

End Module

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.

Nota

En el ejemplo anterior, cualquier excepción distinta de la clase IOException o la clase EndOfStreamException se propaga de nuevo al llamador no controlado.

Vea también

Tareas

Solución de problemas del control de excepciones (Visual Basic)

Referencia

Instrucción Try...Catch...Finally (Visual Basic)

BinaryReader

BinaryWriter

FileStream

Conceptos

Introducción al control de excepciones (Visual Basic)

Tipos de errores (Visual Basic)

Información general sobre el control no estructurado de excepciones (Visual Basic)

Otros recursos

Tareas de control de excepciones (Visual Basic)