martes, 30 de diciembre de 2014

BBVA (Tratamiento de excepciones)

Holas,

Sobre este asunto de excepciones no atrapadas del BBVA que envie hace algunos dias ... (ver excepcion al final de este email) me gustaria hacer un comentario en voz alta que suelo hacer a mis alumnos ...

Todo programa debe tener un catch en el nivel mas alto de codigo que este bajo nuestro control y de esa forma evitar que la excepcion siga subiendo hasta el Sistema operativo y termine en algo asi. de feo en la pantalla del usuario.

Tambien es necesario siempre prestar atencion a la documentacion de las librerias que se utiliza pues si ahi dice que puede lanzar una excepcion hat que ponerle su try/catch siempre.

Sin embargo, con respecto al tratamiento de la excepcion hay varios niveles que me gustaria comentarlos de manera informal.

Nivel 1.- La excepcion es lanzada y el codigo nuestro no la atrapa entonces sigue subiendo hasta el nivel del Sistema Operativo y termina apareciendo en la pantalla del cliente y el desarrollador jamas se entera del problema sucedido.
Esta es la peor situacion.

Nivel 2.- El codigo tiene un catch y muestra un mensaje de error amigable al usuario pero los detalles internos (como el stack) no se muestran.
Esto esta mejor que el anterior pero los desarrolladores no se enteran del problema.

Nivel 3.- Se atrapa la excepcion, se muestra un mensaje amigable pero se guarda la misma en una tabla de la BD donde despues podamos analizar las causas y talvez reproducir el error. Ademas del stack tambien deberiamos guardar el usuario que la provoco, la hora, el IP, el navegador, etc. Con todo eso es mas facil que los desarrolladores puedan corregir el problema facilmente.
El problema aqui es que en un banco podriamos tener decenas de modulos y se formaria un cuello de botella en distribuir los errores a cada equipo.
Esta solucion no es escalable a grandes volumenes de esta ocurrencia.
Piensen por ejemplo en gmail con 400 millones de usuarios.

Nivel 4.- Se hace todo lo del nivel 3 pero ademas se procesa el stack de forma asincrona (sin interruimpir la hebra principal de ejecucion) se identifica (a partir del stack) que modulo es el que causo el problema y se graba toda la informacion en la BD pero ademas se direcciona el error al equipo de desarrollo responsable de la misma.
Esto es mejor que el anterior pero de nuevo no escala si el jefe del equipo tiene que procesar miles o millones de problemas por dia.

Nivel 5.- Capturamos la excepcion, grabamos toda la informacion relacionada a las condiciones en que aparecio la misma. Por otro lado en otro servidor y en otra hebra de menor prioridad nos podriamos conectar al controlador de versiones y detectar en que modulo sucedio y quien fue el que la programó ... asi podriamos direccionar el problema a quien mejor conoce lo que hizo.
De nuevo el problema es que si tuviesemos millares de casos asi seria una tarea no escalable.

Nivel 6.- Hacemos todo lo anterior pero ademas intentamos clasificar la excepcion y acumulamos todas las ocurrencias que sean del mismo caso para presentarlas en forma grafica al responsable.
Ademas podriamos crear un modulo de analisis de ocurrencias como estas de tal forma que al llegar a su trabajo el responsable podria analizar la ocurrencia de estas excepciones por rango de horas en un dia, por origen geografico, por browser, por idioma, etc.
Esta solucion si escala a millones de ocurrencias y permite que el desarrollador pueda corregir lo sucedido.

Nivel Complementario.- Siempre que uno hace un click que carga una nueva funcionalidad lo comun es que se cargue la misma.
Un profesional en computación sabe que el click es algo muy rico y que antes de cargar la nueva funcionalidad debo guardar esa ocurrencia del click junto con el usuario, IP, idioma, browser, hora, dipo de dispositivo, sistema operativo, funcionalidad anterior y posterior. Todo eso se hace de forma asíncrona en una hebra e¡con menor prioridad de tal forma que el usuario no se sienta perjudicado en el tiempo de respuesta de la aplicación.

Solo con esa informacion podria generarse un grafo de transicion de estados en una aplicacion y así podriamos, mas adelante, saber cuales son los caminos por los que se mueve la masa de usuarios. Podríamos detectar que funcionalidades son las mas frecuentes y las menos frecuentes.
Podríamos detectar las condiciones mas frecuentes en las cuales el usuario requiere una funcionalidad, etc.

Esta informacion sumada al Nivel 6 que mencioné anteriormente me da muchos elementos para corregir el software sin tener que preguntarle nada al usuario.

A mi me parece que esto es lo que haría alguien de ciencia de la computación. Es algo de sentido común y no lo he sacado de ningún libro y no estoy aplicando ninguna metodología ... solo sentido común y algo de abstracción.

Saludos
er

Error bean datos not found within scopeHa ocurrido un error procesando: https://150.250.252.104:16640/bdnt_pe_web/error_apl.jspMensaje: bean datos not found within scopeTraza: java.lang.InstantiationException: bean datos not found within scope 
at com.ibm._jsp._error_5F_apl._jspService(_error_5F_apl.java:86) at com.ibm.ws.jsp.runtime.HttpJspBase.service(HttpJspBase.java:93) at javax.servlet.http.HttpServlet.service(HttpServlet.java:856) at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1796) at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:887) at com.ibm.wsspi.webcontainer.servlet.GenericServletWrapper.handleRequest(GenericServletWrapper.java:121) at com.ibm.ws.jsp.webcontainerext.JSPExtensionServletWrapper.handleRequest(JSPExtensionServletWrapper.java:222) at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:348) at com.grupobbva.ii.sf.servlets.OperacionCBTFServlet.formatErrorResponse(OperacionCBTFServlet.java:1532) at com.grupobbva.ii.sf.servlets.OperacionCBTFServlet.processPost(OperacionCBTFServlet.java:2897) at com.ibm.dse.clientserver.servlet.CSReqProtocolServlet.doPost(CSReqProtocolServlet.java) at com.ibm.dse.clientserver.servlet.CSReqProtocolServlet.service(CSReqProtocolServlet.java) at javax.servlet.http.HttpServlet.service(HttpServlet.java:856) at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1796) at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:887) at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:90) at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:1937) at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:130) at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:434) at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpInboundLink.java:373) at com.ibm.ws.http.channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:101) at com.ibm.ws.tcp.channel.impl.WorkQueueManager.requestComplete(WorkQueueManager.java:566) at com.ibm.ws.tcp.channel.impl.WorkQueueManager.attemptIO(WorkQueueManager.java:619) at com.ibm.ws.tcp.channel.impl.WorkQueueManager.workerRun(WorkQueueManager.java:952) at com.ibm.ws.tcp.channel.impl.WorkQueueManager$Worker.run(WorkQueueManager.java:1039) at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1498)

No hay comentarios.:

Publicar un comentario