@@ -26,6 +26,8 @@ internal class ResponseAutoWrapMiddleware
2626
2727 private readonly ILogger _logger ;
2828
29+ private readonly ResponseAutoWrapMiddlewareOptions . MiddlewareExceptionCaptured _middlewareExceptionCaptured ;
30+
2931 private readonly RequestDelegate _next ;
3032
3133 private readonly bool _notCatchExceptions ;
@@ -90,6 +92,7 @@ public ResponseAutoWrapMiddleware(RequestDelegate next,
9092 _notCatchExceptions = ! options . CatchExceptions ;
9193 _throwCaughtExceptions = options . ThrowCaughtExceptions ;
9294 _ignoreOptionsRequest = options . IgnoreOptionsRequest ;
95+ _middlewareExceptionCaptured = options . OnMiddlewareExceptionCaptured ?? LogMiddlewareException ;
9396
9497 var delegateCollection = GetService < ResponseAutoWrapperWorkDelegateCollection > ( ) ;
9598
@@ -123,22 +126,7 @@ public async Task InvokeAsync(HttpContext context)
123126 throw ;
124127 }
125128
126- if ( ! _throwCaughtExceptions )
127- {
128- //不抛出异常时,记录异常
129- var request = context . Request ;
130- //https://github.com/dotnet/aspnetcore/tree/8dd33378697e6f8ca89116170ec3046c185724b6/src/Hosting/Hosting/src/Internal/HostingRequestStartingLog.cs
131- _logger . LogError ( ex , "Request error {Protocol} {Method} {Scheme}://{Host}{PathBase}{Path}{QueryString} {ContentType} {ContentLength}" ,
132- request . Protocol ,
133- request . Method ,
134- request . Scheme ,
135- request . Host . Value ,
136- request . PathBase . Value ,
137- request . Path . Value ,
138- request . QueryString . Value ,
139- request . ContentType ?? string . Empty ,
140- request . ContentLength . HasValue ? request . ContentLength . ToString ( ) : string . Empty ) ;
141- }
129+ var doesExceptionWrapped = false ;
142130
143131 //响应未开始,则包装响应
144132 if ( ! context . Response . HasStarted
@@ -148,6 +136,7 @@ public async Task InvokeAsync(HttpContext context)
148136 if ( response is not null )
149137 {
150138 await WriteResponseWithFormatterAsync ( context , response ) ;
139+ doesExceptionWrapped = true ;
151140 }
152141 }
153142 else //无法对响应进行包装,此时强制向上层抛出异常
@@ -159,6 +148,10 @@ public async Task InvokeAsync(HttpContext context)
159148 {
160149 throw ;
161150 }
151+ else //不抛出异常时,触发回调
152+ {
153+ _middlewareExceptionCaptured ( context . Request , ex , doesExceptionWrapped ) ;
154+ }
162155 }
163156 finally
164157 {
@@ -178,6 +171,31 @@ public async Task InvokeAsync(HttpContext context)
178171
179172 #endregion Public 方法
180173
174+ #region Private 方法
175+
176+ /// <summary>
177+ /// 记录中间件异常
178+ /// </summary>
179+ /// <param name="request">出现异常的请求</param>
180+ /// <param name="exception">异常</param>
181+ /// <param name="hasExceptionWrapped">异常是否已包装</param>
182+ private void LogMiddlewareException ( HttpRequest request , Exception exception , in bool hasExceptionWrapped )
183+ {
184+ //https://github.com/dotnet/aspnetcore/tree/8dd33378697e6f8ca89116170ec3046c185724b6/src/Hosting/Hosting/src/Internal/HostingRequestStartingLog.cs
185+ _logger . LogError ( exception , "Request error {Protocol} {Method} {Scheme}://{Host}{PathBase}{Path}{QueryString} {ContentType} {ContentLength}" ,
186+ request . Protocol ,
187+ request . Method ,
188+ request . Scheme ,
189+ request . Host . Value ,
190+ request . PathBase . Value ,
191+ request . Path . Value ,
192+ request . QueryString . Value ,
193+ request . ContentType ?? string . Empty ,
194+ request . ContentLength . HasValue ? request . ContentLength . ToString ( ) : string . Empty ) ;
195+ }
196+
197+ #endregion Private 方法
198+
181199 #region Internal
182200
183201 private static MediaTypeCollection ? CreateMediaTypeCollection ( IList < MediaTypeHeaderValue > parsedAcceptValues )
0 commit comments