2011-05-27 12 views
5

Copio un fragmento de código de SO como ejemplo. La subrutina contiene un controlador de errores. ¿Debería uno hacer un controlador de errores para todos los Subs?¿Necesitamos crear un controlador de errores para cada subrutina?

Public Sub SubA() 
    On Error Goto ProcError 

    Connection.Open 
    Open File for Writing 
    SomePreciousResource.GrabIt 

ProcExit: 
    Connection.Close 
    Connection = Nothing 
    Close File 
    SomePreciousResource.Release 

    Exit Sub 

ProcError: 
    MsgBox Err.Description 
    Resume ProcExit 
End Sub 

Y, por cierto, ¿cómo el flujo del control dentro de una subrutina cuando el ejecutor código encuentro un Exit Sub, End Sub y Resume? Y cuando encuentra una etiqueta como ProcError: durante la ejecución, ¿la ejecuta o se saltea?

Respuesta

2

Exit Sub va a salir de la subrutina inmediatamente como retorno en Java

End Sub es sólo el marcador para el final del bloque de subrutina como} en Java

Una etiqueta es simplemente una marca en el código que se usa para definir un destino de salto. En caso de que no hayas saltado a la etiqueta pero haya llegado "regularmente", la etiqueta se ignorará, pero el código después de la etiqueta se ejecutará como si no hubiera una etiqueta, el código de tu ejemplo se ejecutará hasta el final. Salga de la instrucción Sub siempre que no se produzca ningún error. Si uno occures saltará a ProcError

curriculum vitae en este caso, ejecutar ProcExit ver más here

+0

Dijiste que se ignorará el bloque de etiquetas, pero ¿cómo reconoce el bloque y lo separa con el resto del código? – lamwaiman1988

+1

@ gunbuster363: Creo que la afirmación de @cmmi es más o menos correcta, aunque no muy clara. Lo que significa "se ignorará la etiqueta" es esto: la etiqueta en sí no hace nada cuando se ejecuta. Sin embargo, el código que sigue a la etiqueta (lo que usted llama el "bloque de etiquetas") no se ignorará y se ejecutará. –

+0

Creo que lo tengo ahora. – lamwaiman1988

9

La respuesta corta es: No, no sólo no se necesidad que tiene un controlador de errores en cada procedimiento, pero, de hecho, generalmente no quiere un controlador de errores en cada procedimiento.

Querrá hacer el manejo de errores donde tenga más sentido hacerlo. A menudo, solo querría un controlador de errores en el procedimiento de nivel más alto, es decir, el que llama a todos los demás; los procedimientos de nivel inferior deberían poner el problema en el piso de arriba y dejar que los errores "burbujeen" hasta el procedimiento de nivel superior. Algunas veces querrá algún tipo de manejo de errores en procedimientos de bajo nivel.

Para más, le remito a estos dos excelentes respuestas por @jtolle:

Además, una búsqueda en Internet revela que hay toda una literatura sobre la web sobre el manejo de errores. ¡Algo de eso está bastante mal, en mi opinión! Pero si se apega a lo que escribí en los primeros dos párrafos, vale la pena considerarlo.

Exit Sub y End Sub son bastante intuitivos: el anterior detiene la ejecución del Sub actual y devuelve el control al procedimiento que lo llamó (o detiene la ejecución por completo si el procedimiento no fue llamado por otro procedimiento). Este último es solo una indicación para el compilador de que aquí el código para este Sub particular termina - y si se ejecuta, End Sub se comporta como Exit Sub.

Resume especifica lo que debe suceder a continuación, una vez que finaliza una rutina de manejo de errores. Plain Resume regresa a la misma declaración que causó el error e intenta ejecutarlo de nuevo. Resume Next omite la instrucción que provocó el error y, en su lugar, va a la instrucción inmediatamente siguiente. Resume mylabel va a la etiqueta mylabel:.

Si una etiqueta como su ProcError: se encuentra en curso de ejecución, entonces no ocurre nada especial, y la ejecución pasa a la siguiente instrucción después de la etiqueta. Por supuesto, en su ejemplo, ProcError: nunca se ejecutará directamente (es decir, no a menos que se genere un error) porque hay un Exit Sub justo antes.


Por cierto, el bloque ProcExit: probablemente debería comenzar con una On Error Resume Next (es decir, seguir cerrando todo y salir sin tener en cuenta los errores) o, alternativamente, como ha señalado @Phydaux, un On Error Goto 0 (en caso de error, se detiene ejecución), de lo contrario, si algo allí desencadena un error, puede entrar en un bucle infinito de ping-pong entre el controlador de errores y el código ProcExit:.

ProcExit: 
    On Error Resume Next ' or, alternatively, On Error Goto 0 
    Connection.Close 
    Connection = Nothing 
    Close File 
    SomePreciousResource.Release 
Exit Sub 
+0

@Jean: +1 para el '' En reanudación de error siguiente'' después de la etiqueta del controlador de errores. Me hizo repensar lo que estoy haciendo. Pero, ¿y si quiero que se ejecute la línea después de que ocurrió el error? ¿Está bien usar '' Resume Next'' en ese caso? Espero que entiendas lo que intento decir (el inglés no es mi lengua materna). – Oneide

+1

Para la sección ProcExit: 'On Error GoTo 0' también puede ser apropiado. Pero definitivamente quieres uno u otro o estás en riesgo de un ciclo infinito. –

+0

@Oneide: ¿Quiere decir que hace el manejo del error y luego ejecuta la línea después de la declaración que causa el error? Sí, en ese caso, 'Resume Next' debe ser la última instrucción de su manejador de errores. Para ser honesto, sin embargo, nunca he encontrado una buena razón para hacer esto. –

Cuestiones relacionadas