Gestión de errores en peticiones Ajax a MVC


Problema

Frecuentemente al realizar llamadas Ajax a servicios se pueden producir errores. Estos errores pueden ser tanto controlados como incontrolados. La cuestión es como realizamos una gestión simple de los mismos.

Propuesta

  • En el servidor
    Añadiremos el atributo [CodeExceptionToHttpFilter] en nuestros métodos ajax.
    Este filtro retornará el error en una respuesta de Http de la siguiente manera:

    • En el Status: 550 si el error es controlado y 551 si es incontrolado. El error es controlado cuando lo hemos generado con la clase CodeException.
    • En el Contenido: el mensaje de error.

    Adjunto ejemplo con un controlador con dos llamadas que generan un error controlado/incontrolado respectivamente.

        public class ThrowExceptionController: Controller
        {
    	    [CodeExceptionToHttpFilter]
            public int ThrowKnownError(CommandWrite command)
            {
    			throw new CodeException("Error Known");
    			return 0;
    		}
    
    	    [CodeExceptionToHttpFilter]
            public int ThrowError(CommandWrite command)
            {
    			throw new Exception("Error UnKnown");
    			return 0;
    		}
    	}
            
  • En el cliente
    En la parte cliente en la función de callback; por ejemplo en nuestro caso ignoramos los errores incontrolados y mostramos un mensaje para los controlado con el mensaje de error.

                $.ajax({
                    url: ...,
                    success: function(d){...},
                    error: function(xhr, status, error){ 
                        switch(xhr.status){
                            case 551:
                                return;
                                break;
                            case 550:
                                alert(xhr.responseText);
                                return;
                                break;
    		    }
                    }
                });	
    

Como funciona:

  • Definir la clase CodeException que encapsule los errores controlados. Esta será la manera que tendrá el atributo para discernir si es un error controlado o no.
        public class CodeException : System.Exception
        {
            public CodeException(String message): base(message)
            {
            }
        }
    
  • Definir la clase atributo. En MVC disponemos la clase FilterAttribute para gestionar los errores que se producen al llamar a los controladores. Nuestra clase CodeExceptionToHttpFilter hereda de la anterior, para gestionar de manera simple los errores en llamadas ajax.
    En el constructor de la clase se asigna la propiedad Order, que es la prioridad con la que actúa el filtro. Tendríamos que asignar una mayor a la que tengamos en el pipeline de MVC.

        public class CodeExceptionToHttpFilter : FilterAttribute, IExceptionFilter
        {
    
            public CodeExceptionToHttpFilter()
            {
                Order = 2;
            }
    
    		public void OnException(ExceptionContext filterContext)
            {
                var codeException = filterContext.Exception as CodeException;
                var response = filterContext.RequestContext.HttpContext.Response;
    			response.StatusCode = (codeException == null)? 550: 551;
                response.ContentType = MediaTypeNames.Text.Plain;
                response.Charset = "utf-8";
                response.Write(filter.Exception.Message);
                filterContext.ExceptionHandled = true;
                response.TrySkipIisCustomErrors = true;
            }
        }
    
    Anuncios
Esta entrada fue publicada en Desarrollo, web y etiquetada , . Guarda el enlace permanente.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s