Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are exceptions an exception to the rule about not modifying the Response after next()?

While trying to find the best approach to implementing a catch-all for any uncaught exceptions I found this.

But, while implementing it, I remembered where I read:

WARNING Don't modify the Response object after calling next()..., as the response may have already started sending and you could cause invalid data to be sent.

pg. 580

Is this an issue when the middleware is acting as a global exception handler before the MVC middleware where it seems reasonable that if the exception middleware were invoked, no response could have been started?

Invoke on Middleware:

public async Task Invoke(HttpContext context)
{
    try
    {
        await _next(context);
    }
    // A catch-all for uncaught exceptions...
    catch (Exception exception)
    {
        var response = context.Response;
        response.ContentType = "application/json";
        response.StatusCode = (int)HttpStatusCode.InternalServerError;

        await response.WriteAsync(...);
    }
}
like image 986
ChiefTwoPencils Avatar asked Nov 06 '22 14:11

ChiefTwoPencils


1 Answers

Of course, I cannot comment on the exact intention the author had in mind when writing that. But the general idea is that you shouldn’t modify a HTTP response when it has already started. This is because the response can already be sent in parts before it is completely constructed. And when you then attempt to change the request then, you will get exceptions that you cannot modify the response.

That is why when you invoke some middleware, and that middleware is expected to produce a response, then you should not modify the response; simply because it will likely fail.

If you invoke some middleware, and that middleware does not produce a response, then of course you are free to still create a response.

For exceptions in particular, middlewares usually produce the response at the very last step, e.g. MVC works with action result objects internally and only at the end those will be executed to produce an actual result on the response. So exceptions will often be triggered before a response is produced. So it is fine to modify the response if you encounter an exception.

The built-in exception handler middleware works pretty much the same btw., so that should be a sign that what you are doing is fine. You should just be aware that modifying the response could potentially fail, so you should handle that case as well, e.g. by checking the HasStarted property.

like image 78
poke Avatar answered Nov 11 '22 14:11

poke