example - ¿Cómo se manejan los errores en los manejadores de errores en VB6?
on error goto vba excel (5)
De su ejemplo, usted está haciendo la limpieza correctamente. Su HandleError solo debe registrar el error, no hacer ninguna UI. La interfaz de usuario se maneja a nivel de formulario.
Lo que necesita cuando ocurre un error es
- Limpiar
- Registra el error
- Levante el error nuevamente a través de Err.Raise
Esto funcionará en la pila de llamadas hasta el evento que llamó al código original. Entonces la secuencia se convertirá
- Limpiar
- Registra el error
- Muestre el diálogo de notificación de error
Tenga en cuenta que su registro de errores puede ser inteligente ya que los registros posteriores del mismo error solo pueden agregarse a la pila de llamadas grabadas.
Desea asegurarse de que CADA evento tenga un controlador de errores. No todos los procedimientos necesitan uno, pero definitivamente cada evento. Los errores no controlados en un evento provocarán que una aplicación VB6 se cierre inesperadamente.
Con frecuencia encuentro esta situación en mis aplicaciones VB6
Private Sub DoSomething
On Error Goto err1
Call ProcessLargeBatch1
Call ProcessLargeBatch2
''... more ...''
Exit Sub
err1:
Call Cleanup ''Specific for DoSomething''
Call HandleError ''General error handling: Logging, message box, ...''
End Sub
El procedimiento de Limpieza a veces revierte acciones, revierte una transacción, elimina archivos temporales, etc. En la mayoría de los casos, esta operación también puede fallar.
¿Qué hago en este caso? Agregaría un On Error Resume Next
en caso de error al On Error Resume Next
del controlador de error, pero eso borra el objeto Err
existente. Agregar un controlador de errores a Cleanup
tiene el mismo problema.
¿Cuál es la mejor manera de garantizar que los errores originales aún se procesen / registren?
EDITAR : Un problema adicional es que también quiero notificar al usuario del error. A veces es importante que la limpieza se realice rápidamente y no quiero que el cuadro de mensaje bloquee la aplicación durante mucho tiempo y realice la limpieza después de que el usuario reconozca el error.
En primer lugar, lea toda la información del objeto Err que necesitará, es decir, número, descripción, etc., borre el error y haga lo que desee.
Cambie la forma en que le informa al usuario que use los valores que ha guardado en la memoria caché y que no use el objeto Err.
Realmente no me gustan los manejadores de errores. Esto es lo que hago;
- Cree una clase o módulo de error que contenga todas las propiedades que contiene el integrado, así como un método CopyError que rellena estas propiedades del objeto err.
- Esté atento a los errores donde pueden aparecer:
.
'' lots of code that will probably work
On Error Resume Next
Open "c:/filethatdoesntexist.txt" For Input As #1
Error.CopyError
On Error Goto 0
Select Case Error.Number
Case 53''File doesn''t exist
'' handle that error here
Case 0
'' no error
Case Else
'' Just throw the error on
Err.Raise Error.Number, Error.Description, ...
End Select
'' more code that will probably work
Registre su error primero. A continuación, realice un On Error Resume Next. Haga que su limpieza se encapsule en métodos que tienen su propio manejo de errores. Esta debería ser tu mejor apuesta.
Si puedo manejar todos los errores en un solo lugar, usualmente pondré en una estructura algo como esto:
Public Sub SubThatShouldHandleErrors()
Const ROUTINE_NAME = "SubThatShouldHandleErrors"
On Error Goto Catch
'' "normal" processing here...
Finally:
'' non-error case falls through to here
'' perform clean-up that must happen even when an error occurred
On Error Goto 0 '' reset: not really needed any more, but it makes me feel more comfortable
Exit Sub
Catch:
'' Error handling here, I may have logging that uses ROUTINE_NAME
Resume Finally
End Sub
Si necesito más de un controlador de errores, intentaré reestructurar mi código para que no sea así, pero si es absolutamente necesario, escribiré un controlador personalizado; mi plantilla es solo una guía.