@@ -170,55 +170,67 @@ private async Task HandleException(HttpContext context, ExceptionDispatchInfo ed
170170 context . Response . StatusCode = _options . StatusCodeSelector ? . Invoke ( edi . SourceException ) ?? DefaultStatusCode ;
171171 context . Response . OnStarting ( _clearCacheHeadersDelegate , context . Response ) ;
172172
173- string ? handler = null ;
174- var handled = false ;
173+ string ? handlerTag = null ;
174+ var handler = Handler . None ;
175175 foreach ( var exceptionHandler in _exceptionHandlers )
176176 {
177- handled = await exceptionHandler . TryHandleAsync ( context , edi . SourceException , context . RequestAborted ) ;
178- if ( handled )
177+ if ( await exceptionHandler . TryHandleAsync ( context , edi . SourceException , context . RequestAborted ) )
179178 {
180- handler = exceptionHandler . GetType ( ) . FullName ;
179+ handler = Handler . IExceptionHandler ;
180+ handlerTag = exceptionHandler . GetType ( ) . FullName ;
181181 break ;
182182 }
183183 }
184184
185- if ( ! handled )
185+ if ( handler == Handler . None )
186186 {
187187 if ( _options . ExceptionHandler is not null )
188188 {
189189 await _options . ExceptionHandler ! ( context ) ;
190+
191+ // If the response has started, assume exception handler was successful.
192+ if ( context . Response . HasStarted )
193+ {
194+ handler = Handler . ExceptionHandler ;
195+ if ( _options . ExceptionHandlingPath . HasValue )
196+ {
197+ handlerTag = _options . ExceptionHandlingPath . Value ;
198+ }
199+ }
190200 }
191201 else
192202 {
193- handled = await _problemDetailsService ! . TryWriteAsync ( new ( )
203+ if ( await _problemDetailsService ! . TryWriteAsync ( new ( )
194204 {
195205 HttpContext = context ,
196206 AdditionalMetadata = exceptionHandlerFeature . Endpoint ? . Metadata ,
197207 ProblemDetails = { Status = context . Response . StatusCode } ,
198208 Exception = edi . SourceException ,
199- } ) ;
200- if ( handled )
209+ } ) )
201210 {
202- handler = _problemDetailsService . GetType ( ) . FullName ;
211+ handler = Handler . IProblemDetailsService ;
212+ handlerTag = _problemDetailsService . GetType ( ) . FullName ;
203213 }
204214 }
205215 }
206216
207- // If the response has already started, assume exception handler was successful.
208- if ( context . Response . HasStarted || handled || _options . StatusCodeSelector != null || context . Response . StatusCode != StatusCodes . Status404NotFound || _options . AllowStatusCode404Response )
217+ if ( handler != Handler . None || _options . StatusCodeSelector != null || context . Response . StatusCode != StatusCodes . Status404NotFound || _options . AllowStatusCode404Response )
209218 {
210- const string eventName = "Microsoft.AspNetCore.Diagnostics.HandledException" ;
211- if ( _diagnosticListener . IsEnabled ( ) && _diagnosticListener . IsEnabled ( eventName ) )
219+ // Customers with an IExceptionHandler that reports it handled the exception could do their own logging.
220+ // Don't log IExceptionHandler handled exceptions if SuppressLoggingIExceptionHandler is set to true.
221+ // Note: Microsoft.AspNetCore.Diagnostics.HandledException is used by AppInsights to log errors so it's also skipped.
222+ if ( handler != Handler . IExceptionHandler || ! _options . SuppressLoggingIExceptionHandler )
212223 {
213- WriteDiagnosticEvent ( _diagnosticListener , eventName , new { httpContext = context , exception = edi . SourceException } ) ;
214- }
224+ const string eventName = "Microsoft.AspNetCore.Diagnostics.HandledException" ;
225+ if ( _diagnosticListener . IsEnabled ( ) && _diagnosticListener . IsEnabled ( eventName ) )
226+ {
227+ WriteDiagnosticEvent ( _diagnosticListener , eventName , new { httpContext = context , exception = edi . SourceException } ) ;
228+ }
215229
216- if ( ! _options . SuppressLoggingOnHandledException )
217- {
218230 _logger . UnhandledException ( edi . SourceException ) ;
219231 }
220232
221- _metrics . RequestException ( exceptionName , ExceptionResult . Handled , handler ) ;
233+ _metrics . RequestException ( exceptionName , ExceptionResult . Handled , handlerTag ) ;
222234 return ;
223235 }
224236
@@ -273,4 +285,12 @@ private static Task ClearCacheHeaders(object state)
273285 headers . ETag = default ;
274286 return Task . CompletedTask ;
275287 }
288+
289+ private enum Handler
290+ {
291+ None ,
292+ IExceptionHandler ,
293+ IProblemDetailsService ,
294+ ExceptionHandler
295+ }
276296}
0 commit comments