martes, 1 de diciembre de 2015
Pues no parecía que esto de la gestión de errores fuera a dar para tanto, pero este es ya el tercer post dedicado a este tema, que por otro lado debemos controlar totalmente cuando comencemos a crear aplicaciones reales con ASP.NET Core y MVC.
Hasta ahora hemos visto cómo gestionar las excepciones producidas desde nuestras aplicaciones utilizando el middleware
Como es habitual, para añadirlo en el pipeline utilizaremos el extensor
La introducción de esa simple línea ya establece un manejador por defecto para los errores HTTP citados que simplemente mostrará el error y su reason phrase, tal y como se muestra en la captura de pantalla adjunta.
Si quisiéramos personalizar un poco el retorno enviado, podríamos hacerlo utilizando la siguiente sobrecarga, en la que indicamos el content-type a retornar, y una plantilla de texto donde "{0}" será sustituido por el código del error capturado:
Hasta aquí, hemos avanzado un poco en el manejo del error, pero aún no es demasiado práctico. Para mejorarlo, podemos usar otra de las sobrecargas de
Pero si preferimos soluciones precocinadas que nos hagan aún la vida más sencilla, todavía tenemos opciones basadas en el mismo middleware más potentes y prácticas que las anteriores, si lo añadimos al pipeline mediante los extensores
Como se puede intuir, el extensor
Desde el lado cliente, se obtendrá en primer lugar una respuesta HTTP 302 con la dirección /error/handle/404, y seguidamente una respuesta HTTP 200 con el contenido que retorne la acción invocada, que por supuesto puede ser una vista completa llena de colores y mensajes simpáticos, como se lleva ahora ;)
Por otra parte, podemos usar
Y creo que esto es todo… salvo que se nos vayan ocurriendo más casos para ir viendo, claro ;)
Publicado en Variable not found.
Hasta ahora hemos visto cómo gestionar las excepciones producidas desde nuestras aplicaciones utilizando el middleware
ExceptionHandlerMiddleware
, y cómo obtener información sobre dichas excepciones desde su código manejador. Esto nos permitía un buen grado de control sobre los errores HTTP 500, pero el amigo Juan, muy atento a lo que íbamos viendo, preguntaba:"Siguiendo con la captura de excepciones, esta vez en mvc6 como se podría capturar los códigos de estado como por ejemplo 404"Obviamente el resto de errores HTTP entre el 400 (errores en cliente) y el 599 (errores en servidor) no son capturados por
ExceptionHandlerMiddleware
porque en realidad no se deben a excepciones generadas desde nuestra aplicación sino a otros problemas que han podido surgir durante el proceso de la petición. Por ello, requieren un tratamiento distinto que de nuevo viene en forma de middleware.Introducing StatusCodePagesMiddleware
Este middleware, que al igual que los ya vistos en otros artículos anteriores se incluye en el paquete Microsoft.AspNetCore.Diagnostics, permite capturar las respuestas sin contenido con códigos HTTP 4xx y 5xx e implementar código personalizado de tratamiento.Como es habitual, para añadirlo en el pipeline utilizaremos el extensor
UseStatusCodePages()
sobre IApplicationBuilder
en el método Configure()
de la clase de inicialización:public void Configure(IApplicationBuilder app) { ... // Initialization code app.UseStatusCodePages(); ... // Other midlewares }Recordad que la posición de los middlewares es crucial, puesto que las peticiones y los retornos serán ejecutados dependiendo del orden en el que han sido añadidos. Dado que este middleware captura retornos, puede ser interesante insertarlo muy al principio del pipeline, para que sólo actúe en el caso de que otros no hayan gestionado el error antes.
La introducción de esa simple línea ya establece un manejador por defecto para los errores HTTP citados que simplemente mostrará el error y su reason phrase, tal y como se muestra en la captura de pantalla adjunta.
Si quisiéramos personalizar un poco el retorno enviado, podríamos hacerlo utilizando la siguiente sobrecarga, en la que indicamos el content-type a retornar, y una plantilla de texto donde "{0}" será sustituido por el código del error capturado:
app.UseStatusCodePages( "text/plain", "Just another HTTP {0} error :)" );El resultado al capturar un error 404 sería el mostrado en la captura de pantalla adjunta.
Hasta aquí, hemos avanzado un poco en el manejo del error, pero aún no es demasiado práctico. Para mejorarlo, podemos usar otra de las sobrecargas de
UseStatusCodePages()
a la que podemos suministrar un delegado con código de tratamiento personalizado del error. En el siguiente ejemplo utilizamos esta característica sólo para enviar directamente un texto personalizado con el error que se ha producido, pero en ese punto podríamos introducir cualquier tipo de código:app.UseStatusCodePages(async ctx => { await ctx.HttpContext.Response.WriteAsync( $"Ops, HTTP {ctx.HttpContext.Response.StatusCode} error!" ); });
Pero si preferimos soluciones precocinadas que nos hagan aún la vida más sencilla, todavía tenemos opciones basadas en el mismo middleware más potentes y prácticas que las anteriores, si lo añadimos al pipeline mediante los extensores
UseStatusCodePagesWithRedirects()
y UseStatusCodePagesWithReExecute()
. Estos dos métodos son lo más parecido que tenemos en ASP.NET Core al atributo redirectMode
de la etiqueta <customErrors>
.Como se puede intuir, el extensor
UseStatusCodePagesWithRedirects()
prepara el middleware para que capture los errores y retorne al cliente una redirección (HTTP 302) hacia la URL que se indique como parámetro. Como ocurría en un ejemplo anterior, de nuevo el "{0}" será sustituido por el código HTTP del error capturado:// En Startup.cs app.UseStatusCodePagesWithRedirects("/error/handle/{0}"); // En Controllers/ErrorController.cs public class ErrorController : Controller { [Route("error/handle/{errorCode}")] public IActionResult Handle(int errorCode) { // Do something and return a view or a content return Content("Error: " + errorCode); } }El resultado si intentamos acceder a un recurso inexistente será el siguiente:
Desde el lado cliente, se obtendrá en primer lugar una respuesta HTTP 302 con la dirección /error/handle/404, y seguidamente una respuesta HTTP 200 con el contenido que retorne la acción invocada, que por supuesto puede ser una vista completa llena de colores y mensajes simpáticos, como se lleva ahora ;)
Por otra parte, podemos usar
UseStatusCodePagesWithReExecute()
para indicar al middleware que debe capturar los errores y generar una petición interna, cuyo resultado será retornado al cliente. Probemos por ejemplo el siguiente código en la inicialización de la aplicación:app.UseStatusCodePagesWithReExecute("/error/handle/{0}");Si se produce un error 404, se procesará internamente una petición hacia /error/handle/404, y el resultado será enviado como contenido de la respuesta al cliente, pero el código HTTP retornado seguirá siendo 404.
Y creo que esto es todo… salvo que se nos vayan ocurriendo más casos para ir viendo, claro ;)
Publicado en Variable not found.
7 Comentarios:
Bien Clara la explicación José Maria, gracias por el aporte!!!
Muchas gracias a ti, Juan!
Está gestión se realiza de la misma manera en MVC?
No conozco el concepto de middleware para MVC, sería lo que hasta ahora ha sido un filtro?
Hola!
Claro, MVC se ejecuta sobre ASP.NET :) De hecho, los ejemplos anteriores usan MVC.
Aunque conceptualmente podrías encontrar alguna similitud con los filtros, no es lo mismo; los filtros son algo propio de MVC y siguen existiendo. Los middlewares arquitecturalmente están por abajo, a nivel de la plataforma ASP.NET.
En este post puedes leer un poco sobre los middlewares y el pipeline de ASP.NET: http://www.variablenotfound.com/2015/02/aspnet-5-donde-esta-mi-globalasax.html.
Saludos!
muchas gracias por la aclaración! le echo un vistazo sin falta!
Excelente!!! Muchas Gracias!!
Muchas gracias a ti por comentar! :)
Enviar un nuevo comentario