从中间件触发异常处理程序(带有状态代码)

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;
}