ErrorHandling Middleware catch 永远不会被捕获
ErrorHandling Middleware catch is never caught
我有这个 ErrorHandlingMiddleware,看起来像这样:
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate _next;
public ErrorHandlingMiddleware(RequestDelegate next)
{
this._next = next;
}
public async Task Invoke(HttpContext context /* other dependencies */)
{
try
{
await _next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception ex)
{
var statusCode = (int)HttpStatusCode.InternalServerError;
if (ex is NotFoundError) statusCode = (int)HttpStatusCode.NotFound;
//else if (ex is MyUnauthorizedException) code = HttpStatusCode.Unauthorized;
//else if (ex is MyException) code = HttpStatusCode.BadRequest;
var error = new AttemptError(statusCode, ex.Message, ex);
context.Response.ContentType = "application/json";
context.Response.StatusCode = statusCode;
return context.Response.WriteAsync(error.ToString());
}
}
我已将此添加到我的 Startup class:
public void Configure(IApplicationBuilder app)
{
app.UseMiddleware<ErrorHandlingMiddleware>();
app.SeedIdentityServerDatabase();
app.UseDeveloperExceptionPage();
app.UseIdentityServer();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "r3plica Identity Server v1");
c.OAuthClientId("swagger");
c.OAuthAppName("Swagger Api UI");
});
app.UseMvc();
}
我希望如果我在我的应用程序中的任何地方抛出异常,它会被捕获并执行以下行:
await HandleExceptionAsync(context, ex);
所以,我设置了一个测试:
throw new Exception();
这是在我的控制器中抛出的。当我 运行 我的应用程序然后调用抛出该异常的端点时,它确实到达了我的 ErrorHandlingMiddleware
的 Invoke
方法,但它没有捕获异常,它只是去 await _next(context)
.....
有谁知道我做错了什么吗?
如果您在 Startup 中的 app.UseDeveloperExceptionPage();
之后调用使用它,您的中间件将会工作。
Handle errors in ASP.NET Core 说
Place the call to UseDeveloperExceptionPage before any middleware that you want to catch exceptions.
我通过创建过滤器解决了这个问题:
public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter
{
public int Order { get; set; } = int.MaxValue - 10;
public void OnActionExecuting(ActionExecutingContext context) { }
public void OnActionExecuted(ActionExecutedContext context)
{
if (context.Exception == null) return;
var attempt = Attempt<string>.Fail(context.Exception);
if (context.Exception is AttemptException exception)
{
context.Result = new ObjectResult(attempt)
{
StatusCode = exception.StatusCode,
};
}
else
{
context.Result = new ObjectResult(attempt)
{
StatusCode = (int)HttpStatusCode.InternalServerError,
};
}
context.ExceptionHandled = true;
}
}
然后这样注册:
services.AddControllers(options => options.Filters.Add(new HttpResponseExceptionFilter()));
我有这个 ErrorHandlingMiddleware,看起来像这样:
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate _next;
public ErrorHandlingMiddleware(RequestDelegate next)
{
this._next = next;
}
public async Task Invoke(HttpContext context /* other dependencies */)
{
try
{
await _next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception ex)
{
var statusCode = (int)HttpStatusCode.InternalServerError;
if (ex is NotFoundError) statusCode = (int)HttpStatusCode.NotFound;
//else if (ex is MyUnauthorizedException) code = HttpStatusCode.Unauthorized;
//else if (ex is MyException) code = HttpStatusCode.BadRequest;
var error = new AttemptError(statusCode, ex.Message, ex);
context.Response.ContentType = "application/json";
context.Response.StatusCode = statusCode;
return context.Response.WriteAsync(error.ToString());
}
}
我已将此添加到我的 Startup class:
public void Configure(IApplicationBuilder app)
{
app.UseMiddleware<ErrorHandlingMiddleware>();
app.SeedIdentityServerDatabase();
app.UseDeveloperExceptionPage();
app.UseIdentityServer();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "r3plica Identity Server v1");
c.OAuthClientId("swagger");
c.OAuthAppName("Swagger Api UI");
});
app.UseMvc();
}
我希望如果我在我的应用程序中的任何地方抛出异常,它会被捕获并执行以下行:
await HandleExceptionAsync(context, ex);
所以,我设置了一个测试:
throw new Exception();
这是在我的控制器中抛出的。当我 运行 我的应用程序然后调用抛出该异常的端点时,它确实到达了我的 ErrorHandlingMiddleware
的 Invoke
方法,但它没有捕获异常,它只是去 await _next(context)
.....
有谁知道我做错了什么吗?
如果您在 Startup 中的 app.UseDeveloperExceptionPage();
之后调用使用它,您的中间件将会工作。
Handle errors in ASP.NET Core 说
Place the call to UseDeveloperExceptionPage before any middleware that you want to catch exceptions.
我通过创建过滤器解决了这个问题:
public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter
{
public int Order { get; set; } = int.MaxValue - 10;
public void OnActionExecuting(ActionExecutingContext context) { }
public void OnActionExecuted(ActionExecutedContext context)
{
if (context.Exception == null) return;
var attempt = Attempt<string>.Fail(context.Exception);
if (context.Exception is AttemptException exception)
{
context.Result = new ObjectResult(attempt)
{
StatusCode = exception.StatusCode,
};
}
else
{
context.Result = new ObjectResult(attempt)
{
StatusCode = (int)HttpStatusCode.InternalServerError,
};
}
context.ExceptionHandled = true;
}
}
然后这样注册:
services.AddControllers(options => options.Filters.Add(new HttpResponseExceptionFilter()));