El mal uso de TRY
¿que es la orden Try?
Esta orden se coloca antes de una sentencia, y hace que si se produce un error, el programa siga ejecutándose sin que se pare, como si no hubiese ocurrido ningún error.
¿cuando lo estamos usando mal?
Al probar un programa, y al ocurrir un error, se suele poner la orden TRY delante de la sentencia
que nos esté dando el error. Con ello, se consigue que el programa siga ejecutandose.
Pero realmente, no hemos resuelto el problema que originaba el error, sino que lo hemos "ocultado".
Esto a la larga provoca que se produzcan otros errores, que son muy difíciles de arreglar ya que pueden están provocados por el error anteriormente "ocultado".
¿cuando es el uso correcto?
Despues de una orden TRY, tendremos que usar ERROR, para analizar que esta provocando error.
Ejemplo:
En el código anterior, hemos intentando borrar un archivo, y si se produce un ERROR se nos muestra un mensaje en la consola.
La clase ERROR tienes otras propiedades que nos dán más información:
error.code: nos dá el nº del error
error.text: nos devuelve un texto que explica que error se ha producido.
error.where: en informa en que linea se ha producido el error
Para más información:
http://gambaswiki.org/wiki/comp/gb/error?l=es
El ejemplo anterior podriamos ampliarlo asi:
Asi mostramos en la consola mucha más información de lo que ha ocurrido.
Un caso real:
Tenemos el siguiente código:
PUBLIC Function Conectar() as connection
$Con=Null ' anulo por si hay conexiones ya abiertas
$Con.Type = "sqlite3" ' definimos el tipo
$Con.Host = user.home & "/directorio" ' definimos directorio donde se encuentra la base de datos
$Con.Name = "test" ' nombre de la base de datos a la que vamos a conectarnos
TRY$Con.Open() ' abrimos la conexión
Return $Con
END
$Con=Null ' anulo por si hay conexiones ya abiertas
$Con.Type = "sqlite3" ' definimos el tipo
$Con.Host = user.home & "/directorio" ' definimos directorio donde se encuentra la base de datos
$Con.Name = "test" ' nombre de la base de datos a la que vamos a conectarnos
TRY$Con.Open() ' abrimos la conexión
Return $Con
END
Como vemos sirve para conectarnos y devolver la conexión a una base de datos SQLite3.
Vemos que tenemos esta linea:
Y a continuación:
Return $Con
Con lo cual lo que estamos haciendo es que, ocurra lo que ocurra (incluso si ocurre un error), al abrir la conexión .open(), vamos a devolverla.
¿y si hay un error en la conexión? dará igual, la devolvemos...(aunque sea NULL).
Si ocurre un error (por ejemplo no encuentra la base de datos), lo que va ha provocar en otra parte del programa más errores, que serán muy difíciles de localizar ya que el error de origen esta aquí.
¿Cual seria la forma correcta de actuar?
Añadir un mensaje y describir el error que se esta produciendo, para que el usuario conozca que esta ocurriendo y/o programador sepa que algo ha ido mal al abrir la base de datos.
PUBLIC SUB Conectar()
$Con=Null ' anulo por si hay conexiones ya abiertas
$Con.Type = "sqlite3" ' definimos el tipo
$Con.Host = user.home & "/directorio" ' definimos directorio donde se encuentra la base de datos
$Con.Name = "test" ' nombre de la base de datos a la que vamos a conectarnos
TRY$Con.Open() ' abrimos la conexión
IF ERROR THEN
Message.error("Error al intentar conectarse a la base de datos")
PRINT ERROR.TEXT
PRINT ERROR.CODE
PRINT ERROR.WHERE
ENDIF
END
$Con=Null ' anulo por si hay conexiones ya abiertas
$Con.Type = "sqlite3" ' definimos el tipo
$Con.Host = user.home & "/directorio" ' definimos directorio donde se encuentra la base de datos
$Con.Name = "test" ' nombre de la base de datos a la que vamos a conectarnos
TRY$Con.Open() ' abrimos la conexión
IF ERROR THEN
Message.error("Error al intentar conectarse a la base de datos")
PRINT ERROR.TEXT
PRINT ERROR.CODE
PRINT ERROR.WHERE
ENDIF
END
Aparte de TRY y ERROR, tenemos disponibles estas dos ordenes FINALLY y CATCH :
FINALLY: Siempre se ejecuta, incluso si hay error
CATCH: Se ejecuta sólo si hay error
' Mostrar un archivo en la consola
SUB PrintFile(FileName AS STRING)
DIM hFile AS File
DIM sLig AS STRING
OPEN FileName FOR READ AS #hFile
WHILE NOT EOF(hFile)
LINE INPUT #hFile, sLig
PRINT sLig
WEND
FINALLY ' Siempre se ejecuta, incluso si hay error
CLOSE #hFile
CATCH ' Se ejecuta sólo si hay error
PRINT "Imposible mostrar el archivo "; FileName
END
SUB PrintFile(FileName AS STRING)
DIM hFile AS File
DIM sLig AS STRING
OPEN FileName FOR READ AS #hFile
WHILE NOT EOF(hFile)
LINE INPUT #hFile, sLig
PRINT sLig
WEND
FINALLY ' Siempre se ejecuta, incluso si hay error
CLOSE #hFile
CATCH ' Se ejecuta sólo si hay error
PRINT "Imposible mostrar el archivo "; FileName
END
Incluso hay un componente llamado gb.logging ( http://gambaswiki.org/wiki/comp/gb.logging y http://www.gambas-es.org/viewtopic.php?f=4&t=3495&highlight=log ), que nos van generar log de los errores.
Estas herramientas nos permiten crear informes de los errores que se producen en la ejecución de la aplicación y que seamos capaces de resolverlos.
Fuentes:
http://gambaswiki.org/wiki/cat/error?l=es
http://gambaswiki.org/wiki/lang/try?l=es
No hay comentarios:
Publicar un comentario