lunes, 5 de mayo de 2008

Manejo de errores


Bueno amigos, el manejo de errores es más que el utilizar el conocido try catch, aunque este es muy bueno para elevar errores que se producen en sub capas, cuando se están utilizando, ya que como sabemos, si trabajamos con aplicaciones portables, debemos manejar y tratar los errores en la interfaz de usuario, así cada desarrollador definirá que errores y que mensajes aplicar cuando se presenta un error.

El siguiente artículo está desglosado en dos partes:

  • Manejo de errores en capas con try catch.
  • Manejo de errores en interfaz y en general.


1 - Manejo de errores en capas con try catch:



La forma más sencilla de tratar y elevar un error desde una capa a otra hasta llegar a la interfaz de usuario es lanzando la excepción, esto lo podemos apreciar a continuación:

try{

}Catch (Exception ex){
throw ex;
}

Yo, cuando defino, ya sea una capa de datos y/o una capa de negocios, nunca trato los errores en estos niveles, ya que si no existe un buen mecanismo de control de errores en estas capas, estos se pierden. Además que al construír aplicaciones portables y reutilizables y, no estar haciendo un buen control de errores en ellas, en la interfaz de usuario se puede perder el error real y el desarrollador puede pasar algunos problemas al tratar de saber cual es el error verdadero. Por lo cual, recomiendo siempre que eleven los errores de las capas capturados en los bloques try catch y, realizar el tratamiento de errores en la interfaz de usuario, en adelante UI.

2 - Manejo de errores en interfaz y en general.


Ahora, es posible manejar y administrar los errores que se presentan en cada una de las páginas que se ejecutan en una aplicación web. Los diversos tipos de errores que se pueden administrar son los siguientes:

  • Capturar errores en una página.
  • Capturar Errores de Aplicación.
  • Manejando los errores en el web.config


Captura de errores en una página:

Cuando estamos en una interfaz, podemos ya manejar los errores con un solo procedimiento, que capturará todos los errores que se presenten en la página, claro esta que podríamos hacerlo con el bloque try catch, pero si podemos crear un método de página que puede controlar los errores que se lanzan desde capas inferiores o que puede capturar los errores que se procuden en la misma página, ¿¿¿para que definir por cada método de página un bloque try catch???. La forma de realizar este ejemplo lo veremos a continuación:


a) Crearemos una página con el nombre wfrError.aspx, dentro de una aplicación o sitio web en vs2003, 2005 y/o 2008.

b) En el método que atiende el evento load del formulario, lanzaremos un evento que desplegará un error, utilizando las siguientes líneas de código:

throw new ApplicationException("Manejo de Error de Interfaz");

Si ejecutamos la página dentro de la aplicación creada veremos que se despliega un error manejado por el IIS, ahora lo que debemos hacer es crear el método de página que controlará todos los errores que se lancen dentro de esta, para ello agregaremos el siguiente procedimiento, el cual estará encargado de capturar y administrar el error que se ha desplegado:

void Page_Error(Object sender, EventArgs args) {

Exception e = Server.GetLastError();

Response.Write("Lo sentimos, se ha producido el siguiente error" + e.ToString());
Server.ClearError();
}


Capturar Errores de Aplicación.

Si no es posible capturar un error en la página, se puede capturar este globalmente creando funciones en el archivo global.asax, específicamente en el método Application_Error.

En este ejemplo defino como crear un archivo de logs, pero yo ya no uso este tipo de manejo de errores debido a que las aplicaciones deben tener permiso de lectura, escritura y modificación, dentro del directorio en donde se escribe el archivo. Yo ahora guardo los log de errores en una tabla que creo en una Base de datos, la cual se puede gestionar de mejor forma si se monta una interfaz de control de errores y de avisos automáticos. El caso es que para este ejemplo se debe hacer lo siguiente:

a) Agregar un nuevo elemento a la solución, seleccionando una aplicación de clase de plantilla global, que lleva por nombre global.asax..

b) En el archivo global.asax agregar las siguientes líneas de código en el método Applicatio_Error:

void Application_Error(object sender, EventArgs e) {
try {
string strFile = Server.MapPath("log.txt");
System.IO.StreamWriter log = new System.IO.StreamWriter(strFile);

System.Exception exc = Server.GetLastError();

log.WriteLine(exc.ToString());
log.Close();
} catch (System.Exception ex) {

}
finally {
Response.Redirect("Pagina de mensaje de error amigable.aspx");
}
}

Ahora, si la página se salta el manejo de errores de página, el error se capturará en este método y se registrará, luego se redireccionará a una página que puede desplegar un mensaje amigable a un usuario.


Manejando los errores en el web.config

Bueno amigos, este tipo de majeo de errores es el más conocido y es el que se utiliza siempre, lo voy a poner solo por los muchachos que consultan mi blogs y que se están iniciando en esto.

El manejo de errores en el web.config, consiste más que en registrar un error, esta asociado a controlar posibles tipos de errores y/o desplegar una interfaz con un mensaje amigable para el usuario, la forma de definir este tipo de manejo de errores es la siguiente:


a) Dentro del nodo system.web del archivo web,config habilitaremos o agregaremos el subnodo customError.

b) En el nodo customError definiremos los siguientes parámetros:

<configuration>
<system.web>
<customErrors mode="RemoteOnly" defaultRedirect="pagina error amigable.aspx"/>
</system.web>
</configuration>


Con esto se logra que cuando exista un error en alguna aplicación se despliegue un mensaje amigable al usuario

c) Tambien es factible definir la redirección de páginas por un un número de error en especícico, por ejemplo:

<configuration>
<system.web>
<customErrors mode="RemoteOnly" defaultRedirect="frmMensaje.aspx>
<error statusCode="500" redirect="PaginaError.aspx"/>
</system.web>
</configuration>


Para probar el funcionamiento del mensaje de error, agregaremos en la página de Default.aspx un link button, apuntando a una página inexistente, al ejecutarse este link button al no existir la página se redireccionará a la página de error en donde se encuentra el mensaje respectivo.



4 comentarios:

Juan David Grisales dijo...

pero en la sección de Capturar Errores de Aplicación.

donde ponemos el metodo Page_Error, en el global.asax, en cada webform que se podria presentar el error, en el iss, en donde?

Mario Roa dijo...

Hay joven Amigo mío, en el post he descrito las distintas formas que existen de manejar errores, si lees bien la descripción que esta encima de este método te dice donde puedes escribir este método, ya sea en la página, con el método Page_Error o en la Aplicación con el método Application_Error, Ahora si quieres una respuesta más técnica, te recomiendo que crees una clase Base que herede de System.Web.UI.Page, coloque ahí el método y todos los métodos que podrías usar en las distintas paginas que desarrollaras. Luego en cada página que crees debes cambiar la herencia a tu clase base y buala, puedes usar no solo el método Page_Error, que su nombre lo dice todo, sino también otros métodos de tu interes.

Anónimo dijo...

esta perfecto lo que indicas pero que pasa si quieres acceder a algo que no existe como por ejemplo:

http://www.mipagina.com/blah

o quieres acceder a una pagina inexistente que no sea aspx como como por ejemplo:

http://www.mipagina.com/blah.html

Si pruebas esto que te digo, no lanza el mensaje personalizado.. sino el mensaje por default de internet explorer :-(

Mario Roa dijo...

Mirate este links, quisas puedas hacer esto antes de llamar una página que no existe.

http://stackoverflow.com/questions/692342/net-httpwebrequest-getresponse-raises-exception-when-http-status-code-400-ba

Salu2