Repository: dotnet/aspnetcore
File: src/Middleware/Diagnostics/src/ExceptionHandler/ExceptionHandlerMiddlewareImpl.cs (C#)

Code before:

        return HandleException(context, edi);

        static async Task Awaited(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)
        {
            ExceptionDispatchInfo? edi = null;
            try
            {
                await task;
            }
            catch (Exception exception)
            {
                // Get the Exception, but don't continue processing in the catch block as its bad for stack usage.
                edi = ExceptionDispatchInfo.Capture(exception);
            }

            if (edi != null)
            {
                await middleware.HandleException(context, edi);
            }
        }
    }

    private async Task HandleException(HttpContext context, ExceptionDispatchInfo edi)
    {
        DiagnosticsTelemetry.AddMetricsTags(context, edi.SourceException);

        var exceptionName = edi.SourceException.GetType().FullName!;

        if ((edi.SourceException is OperationCanceledException || edi.SourceException is IOException) && context.RequestAborted.IsCancellationRequested)
        {
            // Don't log unhandled exception for aborted request.
            _logger.RequestAbortedException();

            if (!context.Response.HasStarted)
            {
                context.Response.StatusCode = StatusCodes.Status499ClientClosedRequest;
            }

            _metrics.RequestException(exceptionName, ExceptionResult.Aborted, handler: null);
            return;
        }

        // We can't do anything if the response has already started, just abort.
        if (context.Response.HasStarted)
        {
            _logger.UnhandledException(edi.SourceException);
            _logger.ResponseStartedErrorHandler();

            _metrics.RequestException(exceptionName, ExceptionResult.Skipped, handler: null);
            edi.Throw();

Review comment (suggestion):
This looks like a behavioral change to add an "error.type" tag to aborted requests. Is this intentional? The SourceException could be noise like errors from Request.Body.ReadAsync which are no way the application's fault.

Code after:

        return HandleException(context, edi);

        static async Task Awaited(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)
        {
            ExceptionDispatchInfo? edi = null;
            try
            {
                await task;
            }
            catch (Exception exception)
            {
                // Get the Exception, but don't continue processing in the catch block as its bad for stack usage.
                edi = ExceptionDispatchInfo.Capture(exception);
            }

            if (edi != null)
            {
                await middleware.HandleException(context, edi);
            }
        }
    }

    private async Task HandleException(HttpContext context, ExceptionDispatchInfo edi)
    {
        var exceptionName = edi.SourceException.GetType().FullName!;

        if ((edi.SourceException is OperationCanceledException || edi.SourceException is IOException) && context.RequestAborted.IsCancellationRequested)
        {
            _logger.RequestAbortedException();

            if (!context.Response.HasStarted)
            {
                context.Response.StatusCode = StatusCodes.Status499ClientClosedRequest;
            }

            _metrics.RequestException(exceptionName, ExceptionResult.Aborted, handler: null);
            return;
        }

        // We can't do anything if the response has already started, just abort.
        if (context.Response.HasStarted)
        {
            _logger.ResponseStartedErrorHandler();

            DiagnosticsTelemetry.ReportUnhandledException(_logger, context, edi.SourceException);
            _metrics.RequestException(exceptionName, ExceptionResult.Skipped, handler: null);
            edi.Throw();
        }

        var originalPath = context.Request.Path;