8/31/2010

AjpdSoft - Cómo capturar errores genéricos ó excepciones en Borland ó Codegear Delphi

AjpdSoft - Cómo capturar errores genéricos ó excepciones en Borland ó Codegear Delphi

Este artículo muestra cómo capturar errores genéricos (de todo tipo), tratamiento de excepciones, en Delphi y mostrar (o no) mensajes a medida, personalizados al usuario final. 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 de cada una de ellas.



Estructuras básicas para la captura de errores o excepciones en Delphi

En primer lugar explicamos las dos estructuras básicas para la captura de errores en el lenguaje de programación Borland o Codegear Delphi:

  • Except: 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. Si no se produce un error se continuará con la ejecución lógica del programa, si se produce un error se ejecutará el código entre el "except" y el "end" y se detendrá la ejecución lógica de la aplicación:
    ...

    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;

  • Finally: en la siguiente estructura el código que va entre el "finally" y el "end" se ejecutará siempre (tanto si se produce un error como si no). Este tipo de captura de errores suele ser usado para finalizar o liberar determinadas variables o estructuras que nos interese que siempre queden liberadas (tanto si se producen errores 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;

Ejemplos de capturas de errores en Delphi con Except ó Finally

Ejemplos con try...except...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, además, podemos personalizar el mensaje de error que se producirá:

... 
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;

Nota: si cambiamos el código dentro del Except por:

  except
raise;
end;

Mostrará el mensaje de error propio generado por Delphi, sin personalizar.

En el ejemplo anterior hemos utilizado el objeto "exception" que es la clase padre. Si queremos mostrar un mensaje aún más personalizado por cada tipo de error que se pueda prodicir 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;

Ejemplos con Try...Finally...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 siempre 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, 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.

Cómo guardar log de errores en una tabla con Delphi

Si queremos guardar los errores para poder consultarlos posteriormente en una tabla de una base de datos, podemos usar el siguiente código en la cláusula "except ... End":

  try
//Código susceptible de provocar un error
md.tcSpam.Open;
except
on e : exception do
begin
//ejecutamos procedure para insertar el mensaje de error en una tabla
insertarLog (now, 'Error', E.Classname + ' : ' + E.Message);
//mostramos el error al usuario
raise;
//realizamos otras tareas, como cerrar una tabla
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", se ejecutará 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 o procedimientos que puedan, a su vez, generar errores dentro de las cláusulas "except" ó "finally". Podríamos cambiar el código anterior por guardar el error en un fichero de texto plano, procedimiento que sería menos susceptible de generar errores que el de guardar en una base de datos.




Clases de excepciones en Delphi

A continuación os mostramos un listado de clases de excepciones de Borland Delphi 6:

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

EurekaLog para captura profesional de errores o excepciones en Delphi

En el siguiente artículo os mostramos qué es EurekaLog y cómo instalarlo y configurarlo para ser usado por los desarrolladores de Delphi, permitiendo mostrar una ventana cuando se produzca un error no capturado personalizada y con información avanzada:

Capura de errores profesional con EurekaLog en Delphi y Visual Studio .Net

Artículos relacionados

Créditos

Artículo realizado íntegramente por Alonsojpd miembro fundador del proyecto AjpdSoft.

1 comentario:

Blogger dijo...

Are you trying to earn cash from your websites/blogs with popup advertisments?
In case you are, did you take a look at PopCash?