从中间件触发异常处理程序(带有状态代码)
Trigger exception handler (with status code) from middleware
我正在尝试从 ASP.NET Core 3.1 中的中间件触发异常(由 /Error
处理)。
异常处理程序在 Startup.cs
中注册(如下所示)而没有 app.UseDeveloperExceptionPage()
,否则工作正常。
app.UseExceptionHandler("/Error");
app.UseStatusCodePagesWithReExecute("/Error", "?statusCode={0}");
但是如何从中间件的 Invoke
方法中触发异常(带有 HTTP 状态代码)?
更新(解决方案): 我主要想从自定义中间件引发异常,但也将状态代码传递给异常处理程序 (/Error
)。我在中间件中使用了这段代码:
public async Task Invoke(HttpContext context)
{
if (context?.Request?.Path.Value.StartsWith("/error"))
{
// allow processing of exception handler
await _next(context);
return;
}
// skip processing, and set status code for use in exception handler
context.SetEndpoint(endpoint: null);
context.Response.StatusCode = 503;
}
根据 document,如果服务器在发送响应 headers 之前捕获到异常,服务器将发送一个 500 - 内部服务器错误响应而没有响应 body。
如果服务器在响应 headers 发送后捕获到异常,服务器将关闭连接。
应用程序不处理的请求由服务器处理。
服务器处理请求时发生的任何异常都由服务器的异常处理处理。 应用的自定义错误页面、异常处理中间件和过滤器不会影响此行为。
如果在应用程序启动时直接抛出异常,则不会进入异常处理程序。
像下面的中间件:
app.Use(async (context, next) =>
{
throw new ArgumentException("aaa");
await next();
});
如果在应用程序完全启动后抛出异常,它将转到异常处理程序,如下例所示。如果您在 url 中键入 home/privacy,您会发现它会转到异常处理程序页面。
app.Use(async (context, next) =>
{
if (context.Request.Path == "/Home/Privacy")
{
throw new ArgumentException("aaa");
}
await next();
});
结果:
我主要是想从自定义中间件引发异常,但也想将状态代码传递给异常处理程序 (/Error
)。我在中间件中使用了这段代码:
public async Task Invoke(HttpContext context)
{
if (context?.Request?.Path.Value.StartsWith("/error"))
{
// allow processing of exception handler
await _next(context);
return;
}
// skip processing, and set status code for use in exception handler
context.SetEndpoint(endpoint: null);
context.Response.StatusCode = 503;
}
我正在尝试从 ASP.NET Core 3.1 中的中间件触发异常(由 /Error
处理)。
异常处理程序在 Startup.cs
中注册(如下所示)而没有 app.UseDeveloperExceptionPage()
,否则工作正常。
app.UseExceptionHandler("/Error");
app.UseStatusCodePagesWithReExecute("/Error", "?statusCode={0}");
但是如何从中间件的 Invoke
方法中触发异常(带有 HTTP 状态代码)?
更新(解决方案): 我主要想从自定义中间件引发异常,但也将状态代码传递给异常处理程序 (/Error
)。我在中间件中使用了这段代码:
public async Task Invoke(HttpContext context)
{
if (context?.Request?.Path.Value.StartsWith("/error"))
{
// allow processing of exception handler
await _next(context);
return;
}
// skip processing, and set status code for use in exception handler
context.SetEndpoint(endpoint: null);
context.Response.StatusCode = 503;
}
根据 document,如果服务器在发送响应 headers 之前捕获到异常,服务器将发送一个 500 - 内部服务器错误响应而没有响应 body。
如果服务器在响应 headers 发送后捕获到异常,服务器将关闭连接。
应用程序不处理的请求由服务器处理。
服务器处理请求时发生的任何异常都由服务器的异常处理处理。 应用的自定义错误页面、异常处理中间件和过滤器不会影响此行为。
如果在应用程序启动时直接抛出异常,则不会进入异常处理程序。
像下面的中间件:
app.Use(async (context, next) =>
{
throw new ArgumentException("aaa");
await next();
});
如果在应用程序完全启动后抛出异常,它将转到异常处理程序,如下例所示。如果您在 url 中键入 home/privacy,您会发现它会转到异常处理程序页面。
app.Use(async (context, next) =>
{
if (context.Request.Path == "/Home/Privacy")
{
throw new ArgumentException("aaa");
}
await next();
});
结果:
我主要是想从自定义中间件引发异常,但也想将状态代码传递给异常处理程序 (/Error
)。我在中间件中使用了这段代码:
public async Task Invoke(HttpContext context)
{
if (context?.Request?.Path.Value.StartsWith("/error"))
{
// allow processing of exception handler
await _next(context);
return;
}
// skip processing, and set status code for use in exception handler
context.SetEndpoint(endpoint: null);
context.Response.StatusCode = 503;
}