title: How to make elmah.io work well with ASP.NET Core and error handing middleware?
body: <p>Note: this question is regarding elmah.io (<a href="https://elmah.io/" rel="nofollow noreferrer">https://elmah.io/</a>), the cloud based exception logging service, and not the traditional Elmah .Net library.</p>
  
  <p>I'm using ASP.NET Core and have a simple exception handling middleware.</p>
  
  <pre><code>public class HandleExceptionMiddleware
  {
      public HandleExceptionMiddleware(RequestDelegate next)
      {
          Next = next;
      }
  
      RequestDelegate Next { get; }
  
      public async Task Invoke(HttpContext httpContext)
      {
          try
          {
              await Next(httpContext);
          }
          catch (Exception ex)
          {
              await HandleExceptionAsync(httpContext, ex);
          }
      }
  
      Task HandleExceptionAsync(HttpContext context, Exception ex)
      {
          var code = HttpStatusCode.InternalServerError;
  
          if (ex is ArgumentException)
              code = HttpStatusCode.BadRequest;
  
          var result = JsonConvert.SerializeObject(new { message = ex.Message });
          context.Response.ContentType = "application/json";
          context.Response.StatusCode = (int)code;
          return context.Response.WriteAsync(result);
      }
  }
  </code></pre>
  
  <p>This middleware will return the following JSON responses depending on the exceptions that it sees:</p>
  
  <p>For ArgumentException:</p>
  
  <pre><code>HTTP/1.1 400 Bad Request
  
  {"message":""}
  </code></pre>
  
  <p>For all other exceptions:</p>
  
  <pre><code>HTTP/1.1 500 Internal Server Error
  
  {"message":""}
  </code></pre>
  
  <p>I'd like elmah.io to log <code>500</code> responses and ignore <code>400</code> responses (which is the default elmah.io configuration). However, when the exception handler and elmah.io are registered in this order in Startup's Configure hook, nothing gets logged in elmah.io:</p>
  
  <pre><code>    app.UseElmahIo("API_KEY", new Guid("LOG_ID"));
      app.UseMiddleware&lt;HandleExceptionMiddleware&gt;()
  </code></pre>
  
  <p>If, however, I change the registration order to the following, everything gets logged (including 400 responses).  This makes sense as elmah.io handles the exceptions before <code>HandleExceptionMiddleware</code> gets a chance to change the response:</p>
  
  <pre><code>    app.UseMiddleware&lt;HandleExceptionMiddleware&gt;()
      app.UseElmahIo("API_KEY", new Guid("LOG_ID"));
  </code></pre>
  
  <p>What is the best way to configure these services so that elmah.io logs 500 responses and ignores 400 responses?</p>
  
  <p>The only workaround I came up with is to create and register 2 exception handing middlewares instead of just 1.  One that registers before and one that registers after elmah.io.  It works, but seems a bit ugly:</p>
  
  <pre><code>    app.UseMiddleware&lt;HandleInternalExceptionMiddleware&gt;() // set 500 responses (these will have already been logged in elmah.io)
      app.UseElmahIo("API_KEY", new Guid("LOG_ID"));
      app.UseMiddleware&lt;HandleExternalExceptionMiddleware&gt;() // set 400 responses but ignore exceptions that should return 500 (these won't be logged in elmah.io)
  </code></pre>
  
  <p>I created a sample project here to demonstrate this behavior:
  <a href="https://github.com/johnnyoshika/elmah-io-experiment" rel="nofollow noreferrer">https://github.com/johnnyoshika/elmah-io-experiment</a></p>