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

Code before:

    /// <summary>
    /// The <see cref="RequestDelegate" /> that will handle the exception. If this is not
    /// explicitly provided, the subsequent middleware pipeline will be used by default.
    /// </summary>
    public RequestDelegate? ExceptionHandler { get; set; }

    /// <summary>
    /// This value controls whether the <see cref="ExceptionHandlerMiddleware" /> should
    /// consider a response with a 404 status code to be a valid result of executing the
    /// <see cref="ExceptionHandler"/>. The default value is false and the middleware will
    /// consider 404 status codes to be an error on the server and will therefore rethrow
    /// the original exception.
    /// </summary>
    public bool AllowStatusCode404Response { get; set; }

    /// <summary>
    /// Gets or sets a delegate used to map an exception to an HTTP status code.
    /// </summary>
    /// <remarks>
    /// If <see cref="StatusCodeSelector"/> is <c>null</c>, the default exception status code 500 is used.
    /// </remarks>
    public Func<Exception, int>? StatusCodeSelector { get; set; }

    /// <summary>
    /// Gets or sets a callback that can be used to suppress logging by <see cref="ExceptionHandlerMiddleware" />.
    /// This callback is only run if the exception was handled by the middleware.
    /// Unhandled exceptions and exceptions thrown after the response has started are always logged.
    /// </summary>
    public Func<ExceptionHandlerSuppressLoggingContext, bool>? SuppressLoggingCallback { get; set; }
}


Review comment (bug):
```suggestion
    /// Gets or sets a callback that can return <see langword="true" /> to suppress the error-level
    /// "UnhandledException" log and the "Microsoft.AspNetCore.Diagnostics.HandledException"
    /// <see cref="EventSource" /> event normally produced by <see cref="ExceptionHandlerMiddleware" />.
```

It is really weird that we chose to use the same boolean to suppress both the "UnhandledException" log and the "HandledException" event which most people would probably think of as opposites, but we should at least call it out.

I still think we should seriously consider not logging the "UnhandledException" for exceptions that are handled by the IExceptionHandler service like #54554 originally requested even if it would be slightly behaviorally breaking like any bug fix. I doubt most people want to be forced to configure a callback just so they don't get an "UnhandledException" log for their handled exceptions.

Maybe instead of having SuppressLoggingCallback default to null, it could default to a Func that returns `true` only for `ExceptionHandledType.ExceptionHandlerService` so we at least give people an out if they really, really want the "UnhandledException" log despite handling the exception even though I doubt anyone actually wants this.

Code after:
    /// <remarks>The default value is <see langword="false"/>.</remarks>
    public bool CreateScopeForErrors { get; set; }

    /// <summary>
    /// The <see cref="RequestDelegate" /> that will handle the exception. If this is not
    /// explicitly provided, the subsequent middleware pipeline will be used by default.
    /// </summary>
    public RequestDelegate? ExceptionHandler { get; set; }

    /// <summary>
    /// This value controls whether the <see cref="ExceptionHandlerMiddleware" /> should
    /// consider a response with a 404 status code to be a valid result of executing the
    /// <see cref="ExceptionHandler"/>. The default value is false and the middleware will
    /// consider 404 status codes to be an error on the server and will therefore rethrow
    /// the original exception.
    /// </summary>
    public bool AllowStatusCode404Response { get; set; }

    /// <summary>
    /// Gets or sets a delegate used to map an exception to an HTTP status code.
    /// </summary>
    /// <remarks>
    /// If <see cref="StatusCodeSelector"/> is <c>null</c>, the default exception status code 500 is used.
    /// </remarks>
    public Func<Exception, int>? StatusCodeSelector { get; set; }

    /// <summary>
    /// Gets or sets a callback that can return <see langword="true" /> to suppress diagnostics in <see cref="ExceptionHandlerMiddleware" />.
    /// <para>
    /// If <see cref="SuppressDiagnosticsCallback"/> is <c>null</c>, the default behavior is to suppress diagnostics if the exception was handled by
    /// an <see cref="IExceptionHandler"/> service instance registered in the DI container.
    /// To always record diagnostics for handled exceptions, set a callback that returns <see langword="false" />.
    /// </para>
    /// <para>
    /// This callback is only run if the exception was handled by the middleware.
    /// Unhandled exceptions and exceptions thrown after the response has started are always logged.
    /// </para>
    /// <para>
    /// Suppressed diagnostics include:
    /// </para>
    /// <list type="bullet">
    ///   <item>
    ///     <description>Logging <c>UnhandledException</c> to <see cref="ILogger"/>.</description>
    ///   </item>
    ///   <item>
    ///     <description>Writing the <c>Microsoft.AspNetCore.Diagnostics.HandledException</c> event to <see cref="EventSource" />.</description>
    ///   </item>
    ///   <item>
    ///     <description>Adding the <c>error.type</c> tag to the <c>http.server.request.duration</c> metric.</description>
    ///   </item>
    /// </list>