Ir al contenido


Foto

Obtener codigo de error de una exception EDatabaseError


  • Por favor identifícate para responder
18 respuestas en este tema

#1 jdepaz

jdepaz

    Advanced Member

  • Miembros
  • PipPipPip
  • 264 mensajes
  • LocationMedellín Colombia

Escrito 25 octubre 2010 - 04:34

hola foreros,

Resulta que estoy trabajando con PostgreSQL 8.X y estoy utilizando los componentes de la paleta SQLdb respectivamente, entonces en un bloque try..except, tengo el codigo para la insercion de un registro, pero cuando se ingresa un ID que ya existe, salta la exepcion, pero la variable que captura el error, solo me muestra el mensaje o el nombre de la clase, aqui el codigo:



delphi
  1. Function TDataModule2.dmInsert_Cliente(Registro:TClient):boolean;
  2. begin
  3. try
  4.   SQLQuery1.SQL.Clear;
  5.   SQLQuery1.SQL.Add('INSERT INTO tbl_cliente (id,nombre,apellido,telefono) ');
  6.   SQLQuery1.SQL.Add('VALUES (:A,:B,:C,:D);');
  7.   SQLQuery1.Params.ParamByName('A').AsInteger:=Registro.Id;
  8.   SQLQuery1.Params.ParamByName('B').AsString:=Registro.Nombre;
  9.   SQLQuery1.Params.ParamByName('C').AsString:=Registro.Apellido;
  10.   SQLQuery1.Params.ParamByName('D').AsString:=Registro.Telefono;
  11.   SQLQuery1.ExecSQL;
  12.   dmconexion.DataModule1.PQConnection1.Transaction.Commit;
  13.   Result:=true;
  14. except
  15.   on E: EDataBaseError Do
  16.   begin
  17.     ShowMessage(E.Message);
  18.   end;
  19. end;
  20. end;     



Ahora bien, lo que quisiera es obtener el codigo del error, en este caso, el codigo de error cuando se intenta grabar un ID ya existente.

Revisando la unit db.pas, esta lo siguiente:



delphi
  1. { Exception classes }
  2.  
  3.   EDatabaseError = class(Exception);
  4.   EUpdateError  = class(EDatabaseError)
  5.   private
  6.     FContext          : String;
  7.     FErrorCode        : integer;
  8.     FOriginalException : Exception;
  9.     FPreviousError    : Integer;
  10.   public
  11.     constructor Create(NativeError, Context : String;
  12.       ErrCode, PrevError : integer; E: Exception);
  13.     Destructor Destroy; override;
  14.     property Context : String read FContext;
  15.     property ErrorCode : integer read FErrorcode;
  16.     property OriginalExcaption : Exception read FOriginalException;
  17.     property PreviousError : Integer read FPreviousError;
  18.   end;



Observando, veo que esta clase tiene la property "ErrorCode",

Entonces, como hago para obtener el ErrorCode?

Espero haberme explicado

Saludos
  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 25 octubre 2010 - 04:39

Hola

No es E.HelpContext ¿?

Salud OS
  • 0

#3 jdepaz

jdepaz

    Advanced Member

  • Miembros
  • PipPipPip
  • 264 mensajes
  • LocationMedellín Colombia

Escrito 25 octubre 2010 - 04:57

Gracias por responder,

Probe con E.HelpContext y bueno al intentar grabar un registro existente,
me muestra el codigo 0, y al provocar alguna otra exception, siempre me muestra el codigo 0.


Saludos

  • 0

#4 German

German

    Member

  • Miembros
  • PipPip
  • 40 mensajes

Escrito 25 octubre 2010 - 06:03



delphi
  1. Function TDataModule2.dmInsert_Cliente(Registro:TClient):boolean;
  2. begin
  3. try
  4.   SQLQuery1.SQL.Clear;
  5.   SQLQuery1.SQL.Add('INSERT INTO tbl_cliente (id,nombre,apellido,telefono) ');
  6.   SQLQuery1.SQL.Add('VALUES (:A,:B,:C,:D);');
  7.   SQLQuery1.Params.ParamByName('A').AsInteger:=Registro.Id;
  8.   SQLQuery1.Params.ParamByName('B').AsString:=Registro.Nombre;
  9.   SQLQuery1.Params.ParamByName('C').AsString:=Registro.Apellido;
  10.   SQLQuery1.Params.ParamByName('D').AsString:=Registro.Telefono;
  11.   SQLQuery1.ExecSQL;
  12.   dmconexion.DataModule1.PQConnection1.Transaction.Commit;
  13.   Result:=true;
  14. except
  15.   on E: EUpdateError Do
  16.   begin
  17.     ShowMessage(Format('Error de actualizacion codigo: %d', [E.ErrorCode]));
  18.   end;
  19.   on A: EDataBaseError Do
  20.   begin
  21.     ShowMessage('Error que no se que es!!');
  22.   end;
  23. end;
  24. end; 

   

  • 0

#5 jdepaz

jdepaz

    Advanced Member

  • Miembros
  • PipPipPip
  • 264 mensajes
  • LocationMedellín Colombia

Escrito 25 octubre 2010 - 08:59

Gracias por la respuesta,
pero necesariamente necesito el codigo de error cuando se intenta ingresar un ID existente,
ya que no quiero que se muestre el mensaje de error por default,

Saludos

  • 0

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 25 octubre 2010 - 09:30

Gracias por la respuesta,
pero necesariamente necesito el codigo de error cuando se intenta ingresar un ID existente,
ya que no quiero que se muestre el mensaje de error por default,

Saludos

Pues no entiendo, el código de German ilustra el caso: se captura la excepción adecuada y se muestra un mensaje personalizado. En el ejemplo incluso hace uso de la lectura de la propiedad ErrorCode.
Ahora quizá, la excepción para el caso de un ID ya existente no sea de tipo EUpdateError sino otra pero el ejemplo de mostrar otro mensaje que no sea por defecto al de la excepción y el uso de ErrorCode está.

O quizá tu te refieres a otra cosa. ¿Podrías aclararnos mejor el panorama?

Saludos,
  • 0

#7 jdepaz

jdepaz

    Advanced Member

  • Miembros
  • PipPipPip
  • 264 mensajes
  • LocationMedellín Colombia

Escrito 26 octubre 2010 - 10:52

Bueno,

Puede ser cualquier error, y creo que cada error tiene su ErrorCode, entonces,
especificamente necesito evaluar cuando por ejemplo suceda el error 100, que seria la violación a una regla de llave primaria, etc., o el error 101 que seria cuando se intenta guardar cierta cantidad de caracteres, digamos 35 en un campo varchar(30), por citar algunos ejemplos.

La cuestion en si, es que estoy haciendo una presentación de una aplicación de 3 capas en un nivel utilizando Lazarus y los componentes que me brinda, sino tendria que utilizar los componentes ZeosLib,

saludos

  • 0

#8 German

German

    Member

  • Miembros
  • PipPip
  • 40 mensajes

Escrito 26 octubre 2010 - 01:57



delphi
  1. Function TDataModule2.dmInsert_Cliente(Registro:TClient):boolean;
  2. begin
  3. try
  4.   SQLQuery1.SQL.Clear;
  5.   SQLQuery1.SQL.Add('INSERT INTO tbl_cliente (id,nombre,apellido,telefono) ');
  6.   SQLQuery1.SQL.Add('VALUES (:A,:B,:C,:D);');
  7.   SQLQuery1.Params.ParamByName('A').AsInteger:=Registro.Id;
  8.   SQLQuery1.Params.ParamByName('B').AsString:=Registro.Nombre;
  9.   SQLQuery1.Params.ParamByName('C').AsString:=Registro.Apellido;
  10.   SQLQuery1.Params.ParamByName('D').AsString:=Registro.Telefono;
  11.   SQLQuery1.ExecSQL;
  12.   dmconexion.DataModule1.PQConnection1.Transaction.Commit;
  13.   Result:=true;
  14. except
  15.   on E: EUpdateError Do
  16.   begin
  17.     if(E.ErrorCode = 100)then
  18.       ShowMessage('Es un error 100!!')
  19.     else if(E.ErrorCode = 101)then
  20.       ShowMessage('Es un error 101!!')
  21.     else then
  22.       ShowMessage('Es un error, pero no 100 ni 101!!');
  23.   end;
  24.   on A: EDataBaseError Do
  25.   begin
  26.     ShowMessage('Error que no se que es!!');
  27.   end;
  28. end;
  29. end;


  • 0

#9 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 26 octubre 2010 - 02:05

Hola,

German, es el segundo código que te edito para añadir las etiquetas DELPHI y dar el formato adecuado. Por favor te agradecería que empezaras a utilizarlas. Aquí tienes una lista de las etiquetas disponibles y cómo usarlas.

Saludos,


  • 0

#10 jdepaz

jdepaz

    Advanced Member

  • Miembros
  • PipPipPip
  • 264 mensajes
  • LocationMedellín Colombia

Escrito 26 octubre 2010 - 02:06

Bueno,

Lo que German acaba de postear es correcto, eso lo entiendo, lo que pasa es que
la variable tipo exception no arroja ningun codigo de error,
utilizando E.HelpContext, solo arroja un valor cero (0), suceda lo que suceda, solo eso un valor 0,
Además, no existe ninguna propiedad "ErrorCode", yo lo escribe para aplicar como ejemplo.


Saludos


  • 0

#11 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 26 octubre 2010 - 07:58

Hola jdepaz,
A ver si te explicas mejor porque no termino de comprender que es lo que quieres hacer.

¿Existe si o no la propiedad ErrorCode? Unos posts antes nos mostrabas un ejemplo de una clase que SI lo tiene pero ahora resulta que dices que no?

¿Como es eso?  ^o| Está muy confuso...

¿A que te refieres cuando dices "yo lo escribe para aplicar como ejemplo"? ¿Esa clase la escribiste como ejemplo? ¿A eso te refieres?

Por favor, claridad en tus palabras... no por ser breve uno termina de explicando lo que en realidad desea hacer.
Prefiero unos párrafos que describan objetivamente el problema, que se comenten los errores y/o advertencias textuales que aparecen, una muestra del código exacto que se se está utilizando.

Esto no es un reproche, es que hay algo que no me cierra con todo esto. Por favor explícate bien.

Saludos,

  • 0

#12 jdepaz

jdepaz

    Advanced Member

  • Miembros
  • PipPipPip
  • 264 mensajes
  • LocationMedellín Colombia

Escrito 26 octubre 2010 - 09:27

Buenas noches,

Creo que mi error esta, en que por decirlo así, pensé que todos estaban en mi sintonia,

Bien ahí voy, caso contrario a Delphi, pero para Lazarus, se tiene la ventaja de poseer los fuentes de FreePascal, entonces como este es un foro sobre Lazarus, pense que se tenia el conocimiento sobre la unit "db.pas", por tal motivo cite parte del fuente de esta, donde se declara parte de la clase EDatabaseError, en este caso la clase EUpdateError que deriva de EDatabaseError.

Ahora bien, quizas lo que queria, era como extraer esa propiedad de la clase EDatabaseError, pero cuando suceda otro tipo de excepcion que no sea un EUpdateError (pero creo que no esta implementado).

Bien, entonces en otros lenguajes, para el manejo de excepciones, estos arrojan un mensaje, un numero de error, etc., pero resulta que esta clase encierra todos los errores en EDatabaseError, cosa que no sucede (creo) con otros componentes, por decirlo asi, (por ejemplo) para Interbase, existe la excepcion EIBDatabaseError, la cual deriva de EDatabaseError, etc.

Creo que voy bien,  (y)

Entonces, vuelvo, lo que necesitaba era obtener el numero de error cuando se viola una regla de llave primaria, pero la variable tipo EDatabaseError no tiene esa propiedad que me indique que código de error sucedió.

Entonces al probar con E.HelpContext, que devuelve un Integer, por cualquier error usando la excepcion EDatabaseError, siempre me arroja un valor 0.

Ya listo, si no me explico, por favor sepan entenderme.


Saludos  :smiley:

Al final ya me di por vencido.







  • 0

#13 German

German

    Member

  • Miembros
  • PipPip
  • 40 mensajes

Escrito 26 octubre 2010 - 11:22



delphi
  1. Function TDataModule2.dmInsert_Cliente(Registro:TClient):boolean;
  2. begin
  3. try
  4.   SQLQuery1.SQL.Clear;
  5.   SQLQuery1.SQL.Add('INSERT INTO tbl_cliente (id,nombre,apellido,telefono) ');
  6.   SQLQuery1.SQL.Add('VALUES (:A,:B,:C,:D);');
  7.   SQLQuery1.Params.ParamByName('A').AsInteger:=Registro.Id;
  8.   SQLQuery1.Params.ParamByName('B').AsString:=Registro.Nombre;
  9.   SQLQuery1.Params.ParamByName('C').AsString:=Registro.Apellido;
  10.   SQLQuery1.Params.ParamByName('D').AsString:=Registro.Telefono;
  11.   SQLQuery1.ExecSQL;
  12.   dmconexion.DataModule1.PQConnection1.Transaction.Commit;
  13.   Result:=true;
  14. except
  15.   on E: EDataBaseError Do
  16.   begin
  17.     if(E is EUpdateError)then
  18.       begin
  19.       if((E as EUpdateError).ErrorCode = 100)then
  20.         ShowMessage('Es un error 100!!')
  21.       else if((E as EUpdateError).ErrorCode = 101)then
  22.         ShowMessage('Es un error 101!!')
  23.       else then
  24.         ShowMessage('Es un error, pero no 100 ni 101!!');
  25.       end
  26.     else 
  27.       ShowMessage('Es un error pero no se cual');
  28.   end;
  29. end;
  30. end;



Con etiquetas y todo!!!

Como recomendacion para jdepaz, podrias empezar por aqui http://www.freepascal.org/docs.var, en especial por aqui http://www.freepasca...#x178-18500014.
  • 0

#14 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 27 octubre 2010 - 09:01

Agregando lo dicho por los demás compañeros, la propiedad HelpContext nunca te mostrará un error, esa propiedad es para el manejo de los archivos de ayuda (sea *.hlp, *.chm. etc.), la solución ya te lo ha dado Germán.

Saludos.
  • 0

#15 jdepaz

jdepaz

    Advanced Member

  • Miembros
  • PipPipPip
  • 264 mensajes
  • LocationMedellín Colombia

Escrito 27 octubre 2010 - 11:21

Gracias,

La solución que plantea German, es cuando suceda una excepcion del tipo Update, pero lo que busco es el tratamiento para cualquier excepcion cuando se requiera hacer un INSERT, pero viendo mas a fondo las excepciones que derivan de EDatabaseError (en FPC) son:

EDdfError
EDbfWriteError
EIBDatabaseError
EUpdateError

Definitivamente al probar el código sugerido, en caso de un INSERT, la ejecución se va a esta parte:


delphi
  1. else 
  2.       ShowMessage('Es un error pero no se cual');







Entonces no hay solución para lo que deseo hacer.


PD: para MySQL si hay varias excepciones derivada de la clase Excepcion



  • 0

#16 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 27 octubre 2010 - 11:28

Pues claro amigo, es que tú mismo debes llamar cada una de las excepciones:



delphi
  1. on E: EDataBaseError Do
  2.   begin
  3.     if(E is EUpdateError)then
  4.       begin
  5.       if((E as EUpdateError).ErrorCode = 100)then
  6.         ShowMessage('Es un error 100!!')
  7.       else if((E as EUpdateError).ErrorCode = 101)then
  8.         ShowMessage('Es un error 101!!')
  9.       else then
  10.         ShowMessage('Es un error, pero no 100 ni 101!!');
  11.       end
  12.     else if (E is EDdfError) then ...
  13.     else if (E is EDbfWriteError) then ...
  14.     else if (E is EIBDatabaseError) then.. //Y así sucesivamente



Saludos.
  • 0

#17 jdepaz

jdepaz

    Advanced Member

  • Miembros
  • PipPipPip
  • 264 mensajes
  • LocationMedellín Colombia

Escrito 27 octubre 2010 - 11:35

Si es cierto, pero especificamente no hay una excepcion para lo que pueda ocurrir con un INSERT, (estoy trabajando con PostgreSQL) ,
las demás excepciones las cite porque son las únicas que están en la clase EDatabaseError.


Saludos


  • 0

#18 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 27 octubre 2010 - 01:15

Hola jdepaz,

Como te han dicho, debes indicar el listado de excepciones que deseas capturar:



delphi
  1. On E: Tipo1 do
  2. On E: Tipo2 do
  3. On E: TipoN do



Y en caso de no tener interés de capturar alguna de listado y ofrecer algún texto para el caso general ya no queda otra que tratarlo con la clase general y por la parte else. Espero que se me entienda.

Para comprobar si existe alguna clase de excepción puntual para ese tipo de error lo que puedes hacer es propagarla o elevarla mediante raise. Con ello debería ser suficiente para que aparezca el cuadro de diálogo con el mensaje del nombre de la excepción. Intuyo que Lazarus será similar a Delphi en este sentido.

Luego vas a tu código y agregas a la lista dicha excepción.

Por otro lado déjame preguntarte, ¿Cuál es el propósito de mostrar el número de error? ¿Tendrá algún interés o funcionalidad alguna aparte de mostrar el número? Si el objetivo es llevar a modo de documentación los posibles errores que pueden detectarse en el sistema lo habitual es llevar una numeración propia para el proyecto y no "propagar" o mostrar el error propio de la excepción. Un método que suele ser utilizado es este:

NroLineaCodigo x LimiteNroErrorExcepcion + NroErrorExcepcion

LimiteNroErrorExcepcion es una constante. Supongamos que el número de error de la excepción mayor consta de 3 dígitos (el rango esperado entonces sería 0 a 999). Entonces LimiteNroErrorExcepcion tendrá el valor 1000.
Luego, hagamos de cuenta que en la línea 123 deseamos capturar un error 101. entonces los cálculos serían:

123 x 1000 + 101 = 123001

De este modo es más fácil localizar un error. Hay quienes suelen agregar un prefijo (sea números o letras) a sus errores para distinguir los módulos. Esto es útil cuando se tienen varias unidades o módulos y existe el riesgo de que en un mismo nro de línea de 2 o más unidades tengamos que detectar un error.

¿Porqué te comento esto? Porque poco uso y utilidad tiene estar mostrando un número de error si después no se le dará seguimiento o interés a ello. El usuario que reciba el número poca importancia la dará... para el será un simple número, o siglas en algunos casos, que no tiene sentido... un error para el será un error como cualquier otro. Por más cartelito bien explicado que tenga. ¿Me explico?

Saludos,
  • 0

#19 jdepaz

jdepaz

    Advanced Member

  • Miembros
  • PipPipPip
  • 264 mensajes
  • LocationMedellín Colombia

Escrito 27 octubre 2010 - 02:34

Bueno,

Lo que estoy haciendo es una presentación/tutorial muy didáctica, entonces, evaluando la inserción de un registro, esta no se podrá llevar a cabo si suceden estos errores (capturados con una excepcion tipo EDatabaseError):


Imagen Enviada

Imagen Enviada



Entonces, creo que cada error tiene su sqlcode.

Lo que veo al final es que la clase EDatabaseError carece de la excepcion para un error de inserción.

Pero bueno, creo que daré por resuelto.

Saludos y gracias a todos


Edito: Hola jdpaz, para las imagenes puedes utilizar la etiqueta de imagen Imagen Enviada la cual muestra la imagen en lugar de la url, o también puedes usar la funcion Adjuntar que está disponible en las Opciones Adicionales ;)
  • 0




IP.Board spam blocked by CleanTalk.