0

I am trying to integrate sentry into my asp .net core app. I can't seem to find a straight answer how to catch the exception before the server throws 500 in asp net core 2.0.

I've searched official docs. Non-development mode.

brthornbury
  • 3,518
  • 1
  • 22
  • 21
  • 2
    Official documentation [Introduction to Error Handling in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/error-handling) – Nkosi Mar 12 '18 at 17:45
  • You can also look into your own custom error handling middleware – Nkosi Mar 12 '18 at 17:47
  • Read the official docs, thanks for the link though. – brthornbury Mar 12 '18 at 18:59
  • Can you please elaborate on why the official documentation is insufficient? It might help if we knew the why as well as the what of your desired solution. – Devin Goble Mar 12 '18 at 22:23

1 Answers1

1

Here is an example of exception handling middleware. It returns custom verbiage with the 500 status code.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Serilog;
using System;
using System.Diagnostics;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Foo
{
    public class ExceptionHandlingMiddleware
    {
        private readonly RequestDelegate next;

        public ExceptionHandlingMiddleware(RequestDelegate next)
        {
            this.next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                await next(context);
            }
            catch (Exception ex)
            {
                await handleExceptionAsync(context, ex);
            }
        }

        private static async Task handleExceptionAsync(HttpContext context, Exception exception)
        {
            string errorCode = calculateErrorCode(context.TraceIdentifier);
            string message = string.Format("An unhandled exception occurred; please contact the help desk with the following error code: '{0}'  [{1}]", errorCode, context.TraceIdentifier);

            Log.Error(exception, message);            

            context.Response.ContentType = "text/plain";
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

            await context.Response.WriteAsync(message);
        }        

        private static string calculateErrorCode(string traceIdentifier)
        {
            const int ErrorCodeLength = 6;
            const string CodeValues = "BCDFGHJKLMNPQRSTVWXYZ";

            MD5 hasher = MD5.Create();

            StringBuilder sb = new StringBuilder(10);

            byte[] traceBytes = hasher.ComputeHash(Encoding.UTF8.GetBytes(traceIdentifier));

            int codeValuesLength = CodeValues.Length;

            for (int i = 0; i < ErrorCodeLength; i++)
            {
                sb.Append(CodeValues[traceBytes[i] % codeValuesLength]);
            }

            return sb.ToString();
        }
    }

    public static class ExceptionHandlingMiddlewareExtensions
    {
        public static IApplicationBuilder UseApiExceptionHandler(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<ExceptionHandlingMiddleware>();
        }
    }
}

Configure in Startup.cs

app.UseApiExceptionHandler();
programmerj
  • 1,634
  • 18
  • 29
  • Really like the thoughtful extension here. This is nice. I wish that custom middleware wasn't the only option, but nonetheless it works. Will approve after testing it out. – brthornbury Mar 12 '18 at 19:01
  • @brthornbury I'd counter that custom middleware should be the only option. In asp.net core, even the out of the box tools are implemented as middleware. It means the extensibility model is cleaner and simpler to understand than having n number of possible options. – Devin Goble Mar 12 '18 at 22:26
  • @kettch If it could be specified in Startup.cs with almost all the other configuration that would make more sense to me. – brthornbury Mar 13 '18 at 02:02