Regalo de vacaciones
Posted: Fri Jul 29, 2011 5:16 pm
Hola,
El tratamiento de excepciones en el código es cada día más habitual; por una parte debe incluirse en las partes mas "delicadas" del fuente y también el uso de componentes OLE, con comportamientos imprevisibles, debe llevar aparejado la protección contra operaciones de "riesgo".
Clipper incluía BEGIN SEQUENCE. [x]Harboures incluyen tb. el comando TRY (Harbour en modo compatibilidad), y al menos Harbour un BEGIN SEQUENCE un poco más cómodo que en Clipper. A pesar de las mejoras en los xHrbs hay algunas cosas que se pueden hacer para automatizar (y por tanto asegurar) nuestro trabajo.
Saludos
El tratamiento de excepciones en el código es cada día más habitual; por una parte debe incluirse en las partes mas "delicadas" del fuente y también el uso de componentes OLE, con comportamientos imprevisibles, debe llevar aparejado la protección contra operaciones de "riesgo".
Clipper incluía BEGIN SEQUENCE. [x]Harboures incluyen tb. el comando TRY (Harbour en modo compatibilidad), y al menos Harbour un BEGIN SEQUENCE un poco más cómodo que en Clipper. A pesar de las mejoras en los xHrbs hay algunas cosas que se pueden hacer para automatizar (y por tanto asegurar) nuestro trabajo.
- Code: Select all Expand view
///////////////////////////
// xTry.Ch
//
//
////////////////////////////////////////
#xCommand xTRY INI TO <oTry> => ;
;
<oTry>:= TxTry():New();;
BEGIN SEQUENCE
#xCommand xTRY END => ;
;
END ;;
oTry:End()
// xTRY CATCH para xTRY INI y xTRY END
// Este en general no sera necesario utilizarlo pq
// normalmente se preguntara y se hara las acciones
// oportunas despues del TRY END
#xCommand xTRY CATCH => ;
;
RECOVER
#xCommand xTRY RETRY INI TO <oTry> ;
[MSGRETRY <cMsgRetry>] => ;
;
DO WHILE .T. ;;
;
<oTry>:= TxTry():New();;
<oTry>:cMsgRetry:= If(<.cMsgRetry.>, <cMsgRetry>, <oTry>:cMsgRetry);;
BEGIN SEQUENCE
#xCommand xTRY RETRY END => ;
;
xTRY END ;;
IF oTry:lError() ;;
IF oTry:lRetry() ;;
LOOP ;;
END ;;
END ;;
EXIT ;;
ENDDO
//eof\\
- Code: Select all Expand view
////////////////////////////////////////
// xTry.Prg eXtended Try
//
//
//
// NOTA:
// ===========================================================
// NO UTILIZAR esta clase y utilizar mejor los comandos
// que hay en xTry.Ch (ver ejemplos)
//
//////////////////////////////////////////////////////////////
*
*
*
*
*
//-------------------------------------------------------------------------//
CLASS TxTry
METHOD New()
METHOD End()
METHOD MsgError() // Mensaje de error 'duro'
METHOD MsgErrorUsuario() // Mensaje error 'blando' para que lo vea el usuario;
// utilizado para operaciones que son mas bien de control de operacion, mas que de error inesperado
METHOD SaveError() // Graba error 'duro'
METHOD lError() INLINE (::oError != NIL)
METHOD lRetry()
METHOD ElaboraError HIDDEN
DATA oError HIDDEN
DATA bError HIDDEN
DATA cMsgRetry
ENDCLASS
*
*
//-------------------------------------------------------------------------//
METHOD New() CLASS TxTry
::bError:= ErrorBlock( { |x| ::oError:= x, Break(x) } )
RETURN Self
*
*
//-------------------------------------------------------------------------//
METHOD End() CLASS TxTry
// Ojo ! *NO* inicializar aqui sobre todo el oError pq
// se puede utilizar, al menos para ::lError(), despues del ::End(); ver
// ejemplos
ErrorBlock(::bError )
RETURN NIL
*
*
//-------------------------------------------------------------------------//
#Define PARAMETROS_DE_USUARIO ;
x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17
METHOD MsgError(PARAMETROS_DE_USUARIO) CLASS TxTry
Local nCount:= PCount()
::ElaboraError(1, nCount, PARAMETROS_DE_USUARIO)
RETURN NIL
*
//-------------------------------------------------------------------------//
METHOD SaveError(PARAMETROS_DE_USUARIO) CLASS TxTry
Local nCount:= PCount()
::ElaboraError(2, nCount, PARAMETROS_DE_USUARIO)
RETURN NIL
*
//-------------------------------------------------------------------------//
METHOD ElaboraError(nQue, nCount, PARAMETROS_DE_USUARIO) CLASS TxTry
Local aPar:= aSize({PARAMETROS_DE_USUARIO}, nCount)
Local oError:= ::oError
*
#Define MSG_ERROR "Se produjo un error controlado !!"
#Define PAR_BASE ;
oError,;
oError:SubSystem(),;
oError:Description,;
oError:Operation,;
oError:SubCode,;
oError:FileName,;
oError:Args,;
oError:OsCode,;
oError:GenCode,;
oError:Severity,;
;
DosError(),;
FError()
IF nQue == 1
IF nCount == 0
msginfo(MSG_ERROR, PAR_BASE)
ELSE
msginfo(MSG_ERROR, PAR_BASE, aPar, aDebug(aPar))
ENDIF
ELSE
IF nCount == 0
GrabaError(MSG_ERROR, PAR_BASE)
ELSE
GrabaError(MSG_ERROR, PAR_BASE, aPar, aDebug(aPar))
ENDIF
ENDIF
RETURN NIL
*
*
*
//-------------------------------------------------------------------------//
METHOD lRetry(cMsgRetry)
Local lRetry
*
IF cMsgRetry == NIL
cMsgRetry:= ::cMsgRetry
ENDIF
IF cMsgRetry == NIL
cMsgRetry:= "Se ha producido un error !!"
ENDIF
*
lRetry:= mMsgYesNo(cMsgRetry+ CRLF+"¿ Reintentar ?")
*
RETURN lRetry
*
*
//-------------------------------------------------------------------------//
METHOD MsgErrorUsuario(cMsgErrorUsuario)
Local lRetry
*
IF cMsgErrorUsuario == NIL
cMsgErrorUsuario:= "No se ha podido realizar la operacion !!"
ENDIF
*
lRetry:= mMsgInfo(cMsgErrorUsuario)
*
RETURN lRetry
*
//eof\\
- Code: Select all Expand view
/////////////////////////////////////////////////////////////////
FUNCTION TestxTry()
#include "xtry.ch"
Local oTry
ALERTA("----Ejemplo 1: Operacion que SI produce un error----")
xTRY INI TO oTry
x:= y // Esto provocara un error
xTRY END
IF oTry:lError()
oTry:MsgError()
ENDIF
ALERTA("----Ejemplo 2: Operacion que NO produce un error----")
xTRY INI TO oTry
x:= 1
xTRY END
IF oTry:lError()
oTry:MsgError()
ENDIF
ALERTA("----Ejemplo 3: Operacion que SI da error, pero posibilidad reintento---")
xTRY RETRY INI TO oTry
x:= y // Esto provocara un error
xTRY RETRY END
IF oTry:lError()
oTry:MsgError()
ENDIF
ALERTA("----Ejemplo 4: Operacion copiado de fichero que SI produce un error----")
xTRY RETRY INI TO oTry
COPY FILE (cOri) TO (cDes)
xTRY RETRY END
IF oTry:lError()
oTry:SaveError()
oTry:MsgErrorUsuario("Fichero no pudo ser copiado !")
ENDIF
ALERTA("----Ejemplo 5: Retry a 'pelo'----")
DO WHILE .T.
xTRY INI TO oTry
x:= y // Esto provocara un error
xTRY END
IF oTry:lError()
IF oTry:lRetry()
LOOP
ENDIF
ENDIF
EXIT
ENDDO
Alerta("-----------------Fin tests xTry----------------")
RETURN NIL
//eof\\
Saludos