Manejo de Errores Más videos
Descripción del tema
En este tutorial veremos como crear una clase para manejar los errores en las peticiones Ajax que realicemos a nuestro servidor. Esto nos permitirá concentrar toda la lógica en una sola clase que podremos mantener de una manera más sencilla.
Estandarizando las respuestas del servidor
Es muy importante definir un estandar para todas las respuestas del servidor, ya sea en caso de éxito o en caso de errores, debemos definir alguna manera de comunicarle al cliente que algo ha fallado en el servidor, para este ejemplo definiremos las siguientes respuestas para éxito y para fallo.
//para el caso de éxito { "control" : { "success" : true }, "output" : {
"users" : [{ "id" : 1, "name" : "John", "lastname": "Doe", "dob" : "1980-05-21 17:23:03" },{ "id" : 2, "name" : "Susan", "lastname": "Smith", "dob" : "1980-10-16 17:23:03" },{ "id" : 3, "name" : "Peter", "lastname": "File", "dob" : "1983-08-03 17:23:03" }] } }
//para el caso de errores { "control" : { "success" : false, "errors" : [{ "code" : 404, "message" : "El recurso no se encontro en este servidor." }] }, "output" : {} }
Para este ejemplo definimos el objeto control que nos define si la petición fue exitosa o no, la propiedad success es la responsable de indicarnos esto, en caso de error se regresa un arreglo con los errores que se ocasionaron, pueden ser de validación o cualquier otro tipo de error, estos mensajes los podemos mostrar al usuario final si es necesario.
Si la respuesta es exitosa entonces el objeto output contendrá la información solicitada, en este ejemplo es un arreglo de usuarios pero podría contener cualquier cosa.
Clase abstracta
En el tema anterior vimos que la clase Ext.data.Connection es la responsable de realizar las peticiones Ajax, por lo tanto si queremos agregar código para manejar los errores que nuestro servidor nos estará enviando debemos extender de esa clase.
Ext.define('MyApp.abstract.data.Connection',{ extend : 'Ext.data.Connection' });
Lo primero que haremos será sobre-escribir el método request para poder definir nuestros propios callbacks de éxito y fallo donde manejaremos los errores de manera adecuada.
Ext.define('MyApp.abstract.data.Connection',{ extend : 'Ext.data.Connection', request : function(options){ options.originalCallbacks = { //step 1 scope : options.scope || this, success : options.success || Ext.emptyFn, failure : options.failure || Ext.emptyFn }; options.scope = this; //step 2 options.success = this.successCallback; options.failure = this.failureCallback; this.callParent([options]); //step 3 } });
- En el paso 1 creamos un objeto llamado originalCallbacks donde almacenaremos temporalmente los callbacks originales ya que los necesitamos llamar más adelante.
- En el paso 2 sobre-escribimos los callbacks originales con las funciones que necesitamos ejecutar para manejar las respuestas de manera adecuada.
- En el paso 3 ejecutamos el método request de la super clase, el cual ejecuta la petición Ajax.
Lo siguiente es definir la función successCallback la cual se encargará de manejar el caso de éxito y la función failureCallback que se encargará de manejar el caso de fracaso.
Ext.define('MyApp.abstract.data.Connection',{ extend : 'Ext.data.Connection', request : function(options){ //... }, successCallback : function(response,options){ console.log('success', options); } failureCallback(response,options){ console.log(options); } });Por el momento solo vamos a imprimir el objeto options en la consola y vamos a crear el HTML para probar el ejemplo. Vamos a llamar el HTML 02-custom-ajax.html y vamos a importar la clase que acabamos de crear: Connection.js.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Custom Ajax</title> <link rel="stylesheet" href="../ext-4.2.1/resources/css/ext-all.css"/> <script type="text/javascript" src="../ext-4.2.1/ext-all-dev.js"></script> <script type="text/javascript" src="Connection.js"></script> <script type="text/javascript"> var Ajax = Ext.create('MyApp.abstract.data.Connection'); //paso 1 Ajax.request({ //paso 2 url : 'serverside/errores.json', success : function(data){ //paso 3 console.log('Success en el Ajax'); }, failure : function(){ console.log('Failure en el Ajax'); } }); </script> </head> <body> </body> </html>
- En el paso 1 creamos una instancia de la clase Connection.
- En el paso 2 usamos el método request de la clase para hacer una petición a la url que le asignamos.
- En el paso 3 definimos el callback de success y failure que por el momento solo imprimen un mensaje en la consola. Estos callbacks no van a ser ejecutados ya que en la clase de Connection los hemos sobre-escrito, aunque como en los callbacks de esa clase estamos imprimiendo lo que tiene el objeto options, vamos a poder ver las funcione originales.
Vamos a cambiar el contenido del método successCallback de la clase Connection, quitamos la impresión a la consola y escribimos el siguiente código:
successCallback : function(response,options){ try{ info = Ext.decode(response.responseText); //paso 1 }catch(e){ info = {control:{success:false}}; } if(info.control.success){ //paso 2 options.originalCallbacks.success.call(options.originalCallbacks.scope,info); }else{ this.failureCallback(response,options); //paso 3 } },
- En el paso 1 estamos decodificando lo que tiene la propiedad responseText, que es básicamente es la respuesta del servidor en formato texto. Lo que hace el método decode es convertir ese texto a objetos de JavaScript. Es necesario que esta parte vaya dentro de un bloque try/catch en caso de que la respuesta del servidor no sea en formato Json, ya que el método decode fallaría y se ejecutaría el método catch. En el método catch solo vamos a definir que success es falso en el objeto control.
- En el paso 2 checamos si la propiedad success es verdadera para poder ejecutar el callback original. Le estamos pasando como parámetro el scope y la respuesta del servidor.
- En el paso 3 si la propiedad success es falsa entonces ejecutamos el método failureCallback que vamos a definir en un momento.
success : function(data){ console.log('Success en el Ajax',data.output.users); },De esta forma estamos imprimiendo la respuesta del servidor en objetos JavaScript.
Ya que definimos el callback de success es necesario definir el callback de failure en la clase Connection.
failureCallback : function(response,options){ var info,error; try{ info = Ext.decode(response.responseText); //paso 1 }catch(e){ info = {control:{success:false}}; } if(info.control.errors){ //paso 2 for(var i=0,len=info.control.errors.length;i<len;i++){ error = info.control.errors[i]; //paso 3 if(error.code === 401){ this.fireEvent('sessionexpired',error); }else{ this.fireEvent('ajaxerror',error); } } }else{ //paso 4 error = {}; switch(response.status){ case 0 : error.message = 'Verifica tu conexión, es posible que este fallando.'; break; case 401 : error.message = 'Tu sesión ha expirado.'; this.fireEvent('sessionexpired',error); break; case 403 : error.message = 'No tienes permisos para acceder este recurso.'; break; case 404 : error.message = 'Recurso no encontrado'; break; case 500 : error.message = 'Error en el servidor'; break; default : error.message = response.statusText; } this.fireEvent('ajaxerror',error); } options.originalCallbacks.failure.call(options.originalCallbacks.scope,error); //paso 5 }
- En el paso 1 decodificamos la respuesta del servidor a objetos JavaScript dentro de un bloque try/catch por si el servidor nos manda un error que no sea Json.
- En el paso 2 verificamos si existe el objeto errors dentro del objeto control, si existe significa que el servidor regresó los errores de manera adecuada en un arreglo.
- En el paso 3 estamos iterando el arreglo errors y por cada error que haya se dispara un evento. Si el error ocurrió porque terminó la sesión disparamos el evento sessionexpired, de lo contrario disparamos el evento ajaxerror.
- En el paso 4 utilizamos un switch donde estamos diferenciando los tipos de errores que nos mandó el servidor utilizando el status de la respuesta; por cada error especificamos un mensaje. Al finalizar el bloque switch disparamos el evento de ajaxerror.
- En el paso 5 simplemente estamos ejecutando el callback original del failure.
MyApp.Ajax.on('ajaxerror',function(error){ Ext.Msg.alert('Error',error.message); });Básicamente lo que hicimos en el código anterior es escuchar el evento y mandar un mensaje de alerta cada vez que se genere un error.
Ahora si podemos probar el ejemplo. Vamos a hacer que se ejecuten los callbacks de failure, para hacer eso vamos a cambiar en el archivo errores.json, la propiedad:
"success" : falseAl ejecutar el ejemplo nos debe aparecer un mensaje en la pantalla con el mensaje de error. Este ejemplo nos muestra que podemos crear nuestro propio sistema de errores con Ext.
Te gustaría recibir más tutoriales como este en tu correo?
Este tutorial pertenece al curso Fundamentos de Ext 4, te recomiendo revises el resto de los tutoriales ya que están en secuencia de menor a mayor complejidad.
Si deseas recibir más tutoriales como este en tu correo te recomiendo registrarte al curso, si ya eres miembro solo identifícate y registrate al curso, si no eres miembro te puedes registrar gratuitamente!
Si no gustas registrarte en este momento no es necesario! Aún así puedes recibir los nuevos tutoriales en tu correo! Jamás te enviaremos Spam y puedes cancelar tu suscripción en cualquier momento.
Regístrate a este curso
Este tutorial pertenece al curso Fundamentos de Ext 4, revisa todos los tutoriales que tenemos en este mismo curso ya que están en secuencia y van de lo más sencillo a lo más complicado.
Tendrás acceso a descargar los videos, códigos y material adicional.
Podrás resolver los ejercicios incluidos en el curso así como los Quizzes.
Llevarás un registro de tu avance.
2Comentarios
Tengo problemas en entender bien la linea: options.originalCallbacks.success.call(options.originalCallbacks.scope,info); El concepto de scope lo entiendo, pero no entiendo que le estoy pasando aqui y que va a hacer con ello Ext
Esa línea es simplemente la ejecución del callback que se definió al hacer el request: Ext.request({ ... success : function(){...} }); En esta línea es donde se ejecuta el success del request.