Digamos que tenemos el siguiente código:
public class MiddleWareFirst { private RequestDelegate next; public MiddleWareFirst(RequestDelegate nextDelegate) { next = nextDelegate; } public async Task Invoke(HttpContext context) { await context.Response.WriteAsync("Start \n"); if (next != null) { await next(context); } } } public class MiddleWareSecond { private RequestDelegate next; public MiddleWareSecond(RequestDelegate nextDelegate) { next = nextDelegate; } public async Task Invoke(HttpContext context) { if (next != null) { await next(context); // <---- should throw the exception caused by MiddleWareThird } } } public class MiddleWareThird { private RequestDelegate next; public MiddleWareThird(RequestDelegate nextDelegate) { next = nextDelegate; } public async Task Invoke(HttpContext context) { throw new System.Exception(); } }y construir la canalización como:
// Configure method in startup.cs app.UseMiddleware<MiddleWareFirst>(); app.UseMiddleware<MiddleWareSecond>(); app.UseMiddleware<MiddleWareThird>(); Puede ver que MiddleWareThird lanza una excepción. Cuando ejecuto la aplicación, puedo ver que el resultado de la página web es "Inicio", lo que me confunde, ¿no debería ser un error 500?
Porque sabemos que await puede lanzar la excepción de una tarea. Entonces, para MiddleWareSecond , dado que no usa el bloque try catch para capturar la excepción, la tarea que regresa a MiddleWareFirst debe contener la excepción internamente. Dado que MiddleWareFirst no utiliza el bloque try catch tampoco, la excepción se propagará al servidor web, lo que debería generar una página de error 500. Pero la salida es normal, entonces, ¿cómo se traga mágicamente la excepción lanzada en MiddleWareThird ?
la excepción se propagará al servidor web, lo que debería generar una página de error 500
Como ya ha iniciado la respuesta con await context.Response.WriteAsync("Start \n"); el código de estado 200 se escribe en el flujo de respuesta según el protocolo HTTP que envía el estado en la primera línea.
Si se lanza una excepción antes WriteAsync , obtendrá 500 del servidor como espera.
Esto es manejado por la infraestructura aspnet core , también en los registros puede notar que se registra la excepción.
Por supuesto, puede tener un middleware personalizado para manejar excepciones como DeveloperExceptionPageMiddleware
public async Task Invoke(HttpContext context) { try { await _next(context); } catch (Exception ex) { //... } }