I'm reading a book which shows that ExceptionHandlerMiddleware re-execute a middleware pipeline in order to generate the response sent to the user as (use app.UseExceptionHandler("/Error");):
And the author says:
Re-executing the middleware pipeline is a great way to keep consistency in your web application for error pages, but there are some gotchas to be aware of. First, middleware can only modify a response generated further down the pipeline if the response hasn’t yet been sent to the client. This can be a problem if, for example, an error occurs while ASP.NET Core is sending a static file to a client. In that case, where bytes have already begun to be sent, the error handling middleware won’t be able to run, as it can’t reset the response.
I'm confused about the part "bytes have already begun to be sent, the error handling middleware won’t be able to run".
Let's say we build the pipeline as:
and let's say a client is requesting a css file, what I understand about the static file middleware is, this middleware read the corresponding file in wwwroot folder and write the content of the css file to HttpContext.Response, so even an error occurs and an exception thrown in the half way through, it just means HttpContext.Response(when it is in the static file middleware) is incomplete, and the ExceptionHandlerMiddleware will catch this exception since ExceptionHandlerMiddleware must use a try and catch to await the Task, so when ExceptionHandlerMiddleware detects an exception was thrown from the middleware below it, then ExceptionHandlerMiddleware can re-execute the pipeline with new path /Error.
So how does the static file middleware send the response to the client before the control falls back to the ExceptionHandlerMiddleware? Isn't that it is the Kestrel web server's or the reverse proxy's job to send the response to clients?

