try page net mvc management handling error custom create catch asp c# asp.net asp.net-mvc exception-handling

c# - page - onexception mvc



¿Qué tan resistente debe ser mi aplicación web? (8)

Creo que me preocupa un poco que estés perdiendo bases de datos con una frecuencia que hace que surja esta pregunta. Incluso en aplicaciones que no son de misión crítica, si pierdes un DB más de una vez a la semana, vería lo que podría hacer para mejorarlo antes de preocuparme por encontrar la manera de solucionar el problema en el usuario final de la aplicación .

Dicho esto, las mejores prácticas de mi empresa incluyen la codificación para que algo como un error de DB conmute por error con gracia en el extremo del usuario a un mensaje de "no se puede conectar" en la salida en lugar de un error de tipo 404 completo. Descubrí que realmente no agrega más de unos minutos al proceso de codificación, y vale la pena el "costo" de no enojar al usuario.

Últimamente, me he encontrado en bastantes discusiones con mi jefe sobre el manejo de excepciones dentro de nuestra aplicación web (aplicación ac # asp.net MVC).

Básicamente, las conversaciones son más o menos así:

Jefe: "Hay algo mal con nuestro programa, la base de datos del cliente x se cayó hoy y todos están viendo la página de error".

Yo: "Casi todas las páginas de la aplicación utilizan la base de datos para algo (excepto la página de error), no hay otra alternativa razonable que no sea mostrar la página de error".

Jefe: "Nuestra aplicación debería ser más resistente: la parte de la aplicación que no requiere acceso a la base de datos todavía debe funcionar".

A menudo, los casos son tan extremos como esto, pero a veces nos encontramos con un caso en el que nos estamos integrando con otro servicio donde todavía podemos mostrar otras partes de la página de manera segura, o completar la operación, aunque con un código molesto como porciones posteriores de el código necesita usar más adelante los resultados de la operación que pueden haber fallado. Si hay muchos puntos de posible falla, esto puede convertirse en un código extremadamente inmanejable.

En general, para una aplicación web "normal" (no de misión crítica, etc.) cuánto tiempo pasan los desarrolladores "buenos" tratando de hacer que su código sea lo suficientemente resistente como para manejar este tipo de situaciones. Mi jefe parece pensar que el código debería ser capaz de manejar casi cualquier situación (¿no puedes simplemente tomar una excepción?). No veo cómo esto puede ser económico cuando hay muchos puntos posibles de falla.


Dejaría que el jefe decidiera. Dígale en aproximadamente unas horas cuánto tardará en hacer que la aplicación sea "resistente" y él decidirá si vale la pena la inversión.


Depende ... muchas páginas web muestran y representan "widgets" individuales. Cada artilugio puede extraer de una fuente de datos diferente ... algunos incluso pueden ser completamente estáticos. Estoy de acuerdo con su jefe desde el punto de vista de que si la carga de un widget falla por alguna razón, aún así deberíamos intentar cargar el resto de la página. Un widget fallido no debe evitar que el usuario interactúe con el resto del sitio.

Como ejemplo de , digamos que la sección "Relacionados" a la derecha de estas respuestas no se carga o que el pie de página no se carga por algún motivo. Diría que es preferible mostrar solo un mensaje de error en esas partes de la página y aún cargar su pregunta y las respuestas, ya que estas no deberían verse afectadas.

Ahora, hay situaciones en las que falla el código que carga todos esos "widgets" ... o falla alguna fuente de datos utilizada por su infraestructura. En estos casos, creo que es razonable mostrar una página de error genérica ... Si el código de carga del marco o "widget" falla por alguna razón, este es un caso excepcional que probablemente no se pueda manejar.

En resumen, casi siempre estoy de acuerdo con su jefe y digo que deben considerarse y manejarse tantos casos de error como sea posible ... y que deberíamos mostrar lo que sea posible para el usuario.


La mayoría de las aplicaciones en las que he trabajado que están fuertemente basadas en datos han sido redirigidas a una página de error personalizada cuando la base de datos principal (es decir, la que activa el 99% de las páginas) está inactiva. (no obstante, desea mostrarles una pantalla personalizada, no solo dejarles obtener la página de error del servidor)

Para servicios externos como ingresar a un servidor SMTP o una base de datos que no es utilizada por gran parte del resto de la aplicación, generalmente tendremos un código que solo muestra comentarios en la página si el servicio / base de datos está inactivo / inaccesible.

Realmente depende del cliente / stakeholder, solo determine qué es lo que quieren que suceda cuando la base de datos esté inactiva y hágalo por ellos. Llevará tiempo, pero no debería llevar a una aplicación no mantenible o cualquier otro horror de codificación.


Su jefe debería haber hablado con el cliente antes de crear la aplicación. Los términos como "no crítico" se deben definir como un número (porcentaje de tiempo de actividad). Algunas aplicaciones requieren diferentes partes de la aplicación para tener diferentes números de tiempo de actividad (lo que sugiere su jefe) y las aplicaciones son arriba / abajo en su conjunto (cómo funciona ahora). La aplicación "flexible" probablemente se escriba de una manera diferente (lecturas distribuidas / escrituras asíncronas, etc.) que la aplicación "normal", por lo que (probablemente) será difícil convertir la aplicación "normal".

Un buen jefe analiza un buen SLA con el cliente de la aplicación y se lo cuenta a los desarrolladores antes de que comience el desarrollo. Por otro lado, un buen desarrollador debería quejarse por su jefe sobre los requisitos incompletos antes de comenzar el desarrollo. Cuando no se menciona nada sobre la disponibilidad en los requisitos, los requisitos son incompletos.

Cuando los requisitos de disponibilidad o escalabilidad de una aplicación existente cambian significativamente, puede ser muy difícil hacer que los cambios en una aplicación sean rentables. Cuando tienes un buen jefe, esos requisitos solo cambiarán significativamente cuando la aplicación tenga mucho más éxito que el estimado inicialmente (como 100 veces más usuarios). En ese caso, el enorme éxito generará suficiente dinero para hacer que sea rentable reescribir grandes partes de la aplicación.


Esta es probablemente una respuesta más académica dado que has heredado este código. Si usa, o más bien si alguien lo usó, el patrón Microsoft.Practices.EnterpriseLibrary.ExceptionHandling ExceptionPolicy, entonces es muy fácil pasar de mostrar una página de error (lanzando una excepción) a comer excepciones y mostrar cuadrículas vacías, listas, etc.

Quizás ya conozcas este pequeño patrón, pero aquí está de todos modos:

try { //get data } catch (Exception ex) { if (ExceptionPolicy.HandleException(ex, "Data Access Exception")) throw ex; }


Probablemente solo muestre una página de error genérica cuando un conjunto vacío de datos con un mensaje de error "fácil de usar" haría.

Entonces, por ejemplo, si está mostrando una lista de usuarios / mensajes / fecha, pero el servicio donde lo recoge está inactivo, probablemente podría mostrar un conjunto vacío.

Entonces, en lugar de mostrar:

500 Server Error .

Podrías mostrar algo como:

User | Message | Date ------------------------------ No data available* * Xyz service is be down.

Su aplicación aún no funcionará, porque los datos no están disponibles, pero en lugar de arrojarlos a la cara del usuario final, podría poner un marcador de posición sin datos.

Esto varía mucho dependiendo de lo que use, pero en términos generales podría ser tan simple como:

List<Data> data = EmptyList<Data>(); try { data = service.GetData(); } catch( ServiceUnavailableException error ) { errorPage.SetMessage( service.GetName() + " service is down "); // log the error message logger.doLog( error ); }

Es decir, inicialice su lista o cualquier estructura a algo vacío, luego complete con el servicio, y si falla (entonces la lista permanecerá vacía) agregue un mensaje de error (fácil de usar por favor) y registre la excepción.


Creo que una vez que comenzamos a practicar algo, creando aplicaciones resilientes para, por ejemplo, pasamos poco tiempo categorizando como normales o de misión crítica y comenzamos a construir aplicaciones resistentes, ha, escalables, etc. para hacer frente a las fallas.

Más esfuerzo es definitivamente necesario para asegurar aplicaciones resilientes, sin embargo, una vez que ese conocimiento se gana e implementa, la próxima vez, se vuelve mucho más fácil. Las bibliotecas genéricas, como Spring o el interruptor automático de Netflix, ya están disponibles y, en la integración, pueden abordar las fallas con elegancia en algunos aspectos. Reintentar una operación idempotente es fácil de implementar también.

Para que una aplicación sea utilizable, debe estar disponible y ser confiable. Casi todas las aplicaciones (distintas de las utilidades de escritorio independientes) son 2 o más aplicaciones escalonadas, lo que significa que la llamada de red estará allí y todos los problemas relacionados con la n / w. Entonces, una vez que comience a practicar, comenzará a implementar patrones de resistencia en todas las aplicaciones.