title: ASP.Net Core middleware cannot set status code on exception because "response has already started"
body: <p>Related: <a href="https://stackoverflow.com/questions/40019012/modify-static-file-response-in-asp-net-core/40019112#40019112">Modify static file response in ASP.NET Core</a></p>
  
  <p>However, I do not understand why the following code works when my business logic throws one of my custom exceptions like <code>UnprocessableException</code>:</p>
  
  <pre><code>try
  {
      await next.Invoke(context);
  }
  catch (UnprocessableException uex)
  {
      Logger.Warn(uex);
      context.Response.StatusCode = 422;
      var responseContent = JsonConvert.SerializeObject(new { uex.Message });
      await context.Response.WriteAsync(responseContent);
  }
  // more specific exceptions resulting in HTTP 4xx status
  </code></pre>
  
  <p>but when a totally unexpected <code>IndexOutOfRangeException</code> is caught by the last <code>catch</code> block in the chain</p>
  
  <pre><code>catch (Exception ex)
  {
      Logger.Error(ex);
      context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
      var responseContent = env.IsDevelopment()
                                ? JsonConvert.SerializeObject(new { ex.Message, ex.StackTrace })
                                : JsonConvert.SerializeObject(new { Message = "An internal error occured" });
      await context.Response.WriteAsync(responseContent);
  }
  </code></pre>
  
  <p>this exception is thrown when trying to set the status code:</p>
  
  <pre><code>System.InvalidOperationException: StatusCode cannot be set, response has already started.
     bei Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.ThrowResponseAlreadyStartedException(String value)
     bei Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.set_StatusCode(Int32 value)
     bei Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.set_StatusCode(Int32 value)
     bei Microsoft.AspNetCore.Http.Internal.DefaultHttpResponse.set_StatusCode(Int32 value)
     bei Anicors.Infrastructure.Middlewares.ScopeMiddleware.&lt;Invoke&gt;d__5.MoveNext()
  </code></pre>