Explica la diferencia entre las cláusulas "except" y "finally". También muestra un listado de las clases de excepción (class exception) y la descripción.
En primer lugar explicamos las dos estructuras básicas para la captura de errores:
1ª En la estructura que mostramos a continuación sólo se ejecutará el código que va entre el "except" y el "end" si se produce un error:
...
begin
... //código que estará fuera de la captura de errores, normalmente
//se colocará fuera el código que sepamos que no puede dar errror
try
// Aquí irá el código susceptible de provocar errores
except
//colocaremos aquí el código que se ejecutará si se produce un error,
//sólo se ejecutará si se produce un error
end;
end;
2ª En la siguiente estructura el código que va entre el "finally" y el "end" se ejecutará siempre (tanto si se produce error como si no): ...
begin
... //código que estará fuera de la captura de errores, normalmente
//se colocará fuera el código que sepamos que no puede dar errror
try
// Aquí irá el código susceptible de provocar errores
finally
//colocaremos aquí el código que se ejecutará tanto si
//se produce un error como si no
end;
end;
Por ejemplo podemos acotar un código susceptible de que se produzca una división por cero con un "try" y un "except" de la siguiente forma: ...
var
numero1, numero2, numero3 : integer;
begin
numero1 := 0;
numero2 := 1;
try
numero3 := numero1 div numero2;
ShowMessage ('Esta línea no se ejecutará pues se producirá el error.');
except
on e : exception do
begin
ShowMessage ('Clase de error: ' + e.ClassName + chr(13) + chr(13) +
'Mensaje del error: ' + e.Message);
end;
end;
end;
En este ejemplo hemos utilizado el objeto "exception" que es la clase padre. Si queremos mostrar un mensaje personalizado por cada tipo de error utilizaremos el siguiente código: ...
var
numero1, numero2, numero3 : integer;
begin
numero1 := 0;
numero2 := 1;
try
numero3 := numero1 div numero2;
ShowMessage ('Esta línea no se ejecutará pues se producirá el error.');
except
on e : EDivByZero do
begin
ShowMessage ('Ha intentado dividir un número por cero.');
end;
else
ShowMessage ('Se ha producido un error: ' + chr(13) + chr(13) +
'Clase de error: ' + e.ClassName + chr(13) + chr(13) +
'Mensaje del error: ' + e.Message);
end;
end;
Un ejemplo utilizando "finally" (código que siempre se ejecutará tanto si hay error como si no): procedure TformMenuPrincipal.actCuentasEmailExecute(Sender: TObject);
var
formulario : TformCuentas;
begin
formulario := TformCuentas.Create(Application);
try
formulario.ShowModal;
finally
formulario.Free;
end;
end;
En este caso hemos utilizado un ejemplo que crea un formulario y lo muestra modal, si la línea "formualario.ShowModal" da un error (por cualquier causa) se ejecutará lo que haya en el "finally" y si no da error también, con lo cual, en este caso, nos aseguramos de que el formulario modal se libera tras su ejecución.Con lo cual utilizaremos "finally" siempre que nos interese que se ejecute código tanto si se produce un error como si no se produce, por ejemplo cuando creamos un objeto y queramos que este se libere sea cual sea el resultado de la creación. Y utilizaremos "except" en los demás casos, cuando queramos que el código de error sólo se ejecute cuando éste se produzca.
Otro ejemplo de utilización de "try ... except":
try
md.tcSpam.Open;
except
on e : exception do
begin
insertarLog (now, 'Error', E.Classname + ' : ' + E.Message);
md.tcSpam.Close;
end;
end;
En este caso "md.tcSpam.Open" es un TQuery con una consulta SQL asociada, si se produce algún error se ejecutará lo que haya dentro del "except", en este caso un procedimiento llamado "insertarLog" que, a su vez, inserta un registro en una base de datos para guardar los posibles errores de la aplicación. A continuación os mostramos el código del procedimiento "insertarLog": procedure insertarLog (fecha : TDateTime; tipo : string; mensaje : string);
begin
md.tLog.Open;
md.tLog.Insert;
md.tLogFECHA.Value := fecha;
md.tLogTIPO.Value := tipo;
md.tLogTEXTO.Value := mensaje;
md.tLog.Post;
md.tLog.Close;
end;
Donde md es el nombre del módulo de datos (TDataModule) en el que está el TTable "tLog" que apunta a una tabla de la base de datos con la siguiente estructura (MySQL): CREATE TABLE `log` (
`ID` int(10) NOT NULL auto_increment,
`FECHA` datetime default NULL,
`TEXTO` varchar(255) default NULL,
`TIPO` varchar(20) default NULL,
PRIMARY KEY (`ID`)
)
Aunque hemos de reconocer que no es conveniente utilizar funciones/procedimientos/código que pueda generar errores dentro de las cláusulas "except" ó "finally". A continuación os mostramos un listado de clases de excepciones:
Exception Base class
EAbort Abort without dialog
EAbstractError Abstract method error
AssertionFailed Assert call failed
EBitsError Boolean array error
ECommonCalendarError Calendar calc error
EDateTimeError DateTime calc error
EMonthCalError Month calc error
EConversionError Raised by Convert
EConvertError Object convert error
EDatabaseError Database error
EExternal Hardware/Windows error
EAccessViolation Access violation
EControlC User abort occured
EExternalException Other Internal error
EIntError Integer calc error
EDivByZero Integer Divide by zero
EIntOverflow Integer overflow
ERangeError Out of value range
EMathError Floating point error
EInvalidArgument Bad argument value
EInvalidOp Inappropriate operation
EOverflow Value too large
EUnderflow Value too small
EZeroDivide Floating Divide by zero
EStackOverflow Severe Delphi problem
EHeapException Dynamic memory problem
EInvalidPointer Bad memory pointer
EOutOfMemory Cannot allocate memory
EInOutError IO error
EInvalidCast Object casting error
EInvalidOperation Bad component op
EMenuError Menu item error
EOSError Operating system error
EParserError Parsing error
EPrinter Printer error
EPropertyError Class property error#
EPropReadOnly Invalid property access
EPropWriteOnly Invalid property access
EThread Thread error
EVariantError Variant problem
No hay comentarios:
Publicar un comentario