miércoles, 22 de julio de 2009

Dónde utilizar manejo de excepciones (Try-Catch-Finaly)

El try-catch no puede ser utilizado para todas las validaciones que tengamos en la aplicación, tampoco podemos meterla dentro de un gran try porque es más difícil seguir el control del error. Además de que perdemos un poco de performance ahí. 

Entonces dentro las buenas prácticas para utilizar tenemos:

  1. Para validar valores nulos o rango de valores NO usar try-catch, mejor usar condiciones.
  2. Cuando usas Streams de cualquier tipo (Memory, File, Network, etc) y cuando abres conexiones (Tcp, Udp, Serial, etc) SIEMPRE usar try-catch-finaly. Y en el finaly cerrar la conexión o el stream, así nos aseguramos de que siempre quede cerrado.
  3. Intentar siempre no atajar las excepciones declarando Exception en el catch, sino por la excepción que lance el método, es decir, si vas a ejecutar un método que abre un archivo y ese archivo no existe, lo más seguro es que lance un FileNotFoundException, entonces se hace un catch por ese y por cada uno de las posibles excepciones del método. Así tenemos más control sobre el error.
  4. Las transacciones también deben de escribirse dentro de un bloque try-catch, y en el catch llamar al rollback, ya que si ocurre un error se cancela todo el proceso y mantenemos la integridad de la data.


Un pequeño ejemplo de lo mencionado anteriormente:


public void OpenDocument(string filepath)

{

    //Declaramos el stream y el reader afuera del try

    //para que puedan ser accesados en el finaly

    FileStream fileStream = null;

    StreamReader reader = null;

 

    try

    {

        //abrimos el archivo

        fileStream = new FileStream(filepath, FileMode.Open);

        //creamos el reader

        reader = new StreamReader(fileStream);

        //leemos el archivo

        string filecontent = reader.ReadToEnd();

    }

    catch (FileNotFoundException fileEx)

    {

        //se captura la excepción si no existe el archivo

        //que viene como parámetro del método open y se

        //muestra el error.

        MessageBox.Show("No se pudo encontrar el archivo", "Error");

    }

    finally

    {

        //El bloque finaly SIEMPRE se ejecuta, no importa

        //lo que pase, por eso cerramos el stream aquí, sea que

        //hayamos leido correctamente el archivo o que se

        //produsca una excepción, SIEMPRE se ejecuta el finaly.

        reader.Close();

    }

}

La próxima entrada será de Streaming, así que no se la pierdan!


finaly

{

       Gracias por leer!

4 comentarios:

  1. Si existe un Application.Exit() de por medio a mitad del catch del ejemplo, el finally aún se ejecuta?

    ResponderEliminar
  2. Claro que se ejecuta, tu mismo lo dijiste: "el finaly es amén!" jaja

    De hecho, pasa por el finaly al momento de interrumpirse el contexto actual de ejecución que, en éste caso, sería el catch.

    ResponderEliminar
  3. Según la clase a la que concurrí el viernes pasado en la facultad, el único caso en que no se ejecuta el bloque "finally" es el el caso de un exit().
    Lo acabo de comprobar y es asi.
    Saludos

    ResponderEliminar
  4. Leok,

    Pordías aportar un demo? Yo mismo he probado esto antes y si pasa por el finally, pero bueno, posiblemente yo esté equivocado.

    Un saludo.

    ResponderEliminar