/// <summary> /// Invokes this middleware instance on the specified context. /// </summary> /// <param name="context">The context.</param> /// <returns>A middleware invocation/execution task.</returns> public async Task Invoke(HttpContext context) { // as we learned from a field issue, apparently a middleware can even be invoked without a valid HttPContext: string requestId = null; requestId = context?.Features? .Get <IHttpRequestIdentifierFeature>()? .TraceIdentifier; #if (NETSTANDARD2_1 || NETCOREAPP3_0) context?.Request.EnableBuffering(); #else context?.Request.EnableRewind(); #endif using (_logger.BeginScope($"Request: {requestId ?? string.Empty}")) { NetworkTelemetry networkTelemetry = null; try { if (TelemetryCollector.Instance.IsAutocollecting && context != null && context.Request != null) { int?telemetryStatusCode = null; telemetryStatusCode = context?.Response?.StatusCode; networkTelemetry = new NetworkTelemetry( method: context.Request.Method, url: context.Request.Host.Value + context.Request.Path, eventStart: DateTime.UtcNow, eventEnd: null, statusCode: telemetryStatusCode ); TelemetryCollector.Instance.Capture(new Telemetry(TelemetrySource.Server, TelemetryLevel.Info, networkTelemetry)); } if (RollbarScope.Current != null && RollbarScope.Current.HttpContext != null) { RollbarScope.Current.HttpContext.HttpAttributes = new RollbarHttpAttributes(context); } await this._nextRequestProcessor(context); } catch (System.Exception ex) { if (networkTelemetry != null) { networkTelemetry.StatusCode = context?.Response?.StatusCode.ToString(); networkTelemetry.FinalizeEvent(); } if (!RollbarLocator.RollbarInstance.Config.CaptureUncaughtExceptions) { // just rethrow since the Rollbar SDK is configured not to auto-capture // uncaught exceptions: throw; } if (RollbarScope.Current != null && RollbarLocator.RollbarInstance.Config.MaxItems > 0 ) { RollbarScope.Current.IncrementLogItemsCount(); if (RollbarScope.Current.LogItemsCount == RollbarLocator.RollbarInstance.Config.MaxItems) { // the Rollbar SDK just reached MaxItems limit, report this fact and pause further logging within this scope: RollbarLocator.RollbarInstance.Warning(RollbarScope.MaxItemsReachedWarning); throw; } else if (RollbarScope.Current.LogItemsCount > RollbarLocator.RollbarInstance.Config.MaxItems) { // just rethrow since the Rollbar SDK already exceeded MaxItems limit: throw; } } else { IRollbarPackage rollbarPackage = new ExceptionPackage(ex, $"{nameof(RollbarMiddleware)} processed uncaught exception."); if (context != null) { if (context.Request != null) { rollbarPackage = new HttpRequestPackageDecorator(rollbarPackage, context.Request, true); } if (context.Response != null) { rollbarPackage = new HttpResponsePackageDecorator(rollbarPackage, context.Response, true); } } RollbarLocator.RollbarInstance.Critical(rollbarPackage); } throw new RollbarMiddlewareException(ex); } finally { if (context != null && context.Response != null && RollbarScope.Current != null && RollbarScope.Current.HttpContext != null && RollbarScope.Current.HttpContext.HttpAttributes != null ) { RollbarScope.Current.HttpContext.HttpAttributes.ResponseStatusCode = context.Response.StatusCode; } if (networkTelemetry != null) { if (string.IsNullOrWhiteSpace(networkTelemetry.StatusCode)) { networkTelemetry.StatusCode = context?.Response?.StatusCode.ToString(); } networkTelemetry.FinalizeEvent(); } } } }
/// <summary> /// Invokes this middleware instance on the specified context. /// </summary> /// <param name="context">The context.</param> /// <returns>A middleware invocation/execution task.</returns> public async Task Invoke(HttpContext context) { // as we learned from a field issue, apparently a middleware can even be invoked without a valid HttPContext: string requestId = null; requestId = context?.Features? .Get <IHttpRequestIdentifierFeature>()? .TraceIdentifier; using (_logger.BeginScope($"Request: {requestId ?? string.Empty}")) { NetworkTelemetry networkTelemetry = null; try { if (TelemetryCollector.Instance.IsAutocollecting && context != null && context.Request != null) { int?telemetryStatusCode = null; telemetryStatusCode = context?.Response?.StatusCode; networkTelemetry = new NetworkTelemetry( method: context.Request.Method, url: context.Request.Host.Value + context.Request.Path, eventStart: DateTime.UtcNow, eventEnd: null, statusCode: telemetryStatusCode ); TelemetryCollector.Instance.Capture(new Telemetry(TelemetrySource.Server, TelemetryLevel.Info, networkTelemetry)); } RollbarScope.Current.HttpContext.HttpAttributes = new RollbarHttpAttributes(context); await this._nextRequestProcessor(context); } catch (System.Exception ex) { if (networkTelemetry != null) { networkTelemetry.StatusCode = context?.Response?.StatusCode.ToString(); networkTelemetry.FinalizeEvent(); } if (!RollbarLocator.RollbarInstance.Config.CaptureUncaughtExceptions) { // just rethrow since the Rollbar SDK is configured not to auto-capture uncaught exceptions: throw ex; } if (RollbarScope.Current != null && RollbarLocator.RollbarInstance.Config.MaxItems > 0 ) { RollbarScope.Current.IncrementLogItemsCount(); if (RollbarScope.Current.LogItemsCount == RollbarLocator.RollbarInstance.Config.MaxItems) { // the Rollbar SDK just reached MaxItems limit, report this fact and pause further logging within this scope: #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed RollbarLocator.RollbarInstance.Warning(RollbarScope.MaxItemsReachedWarning); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed throw ex; } else if (RollbarScope.Current.LogItemsCount > RollbarLocator.RollbarInstance.Config.MaxItems) { // just rethrow since the Rollbar SDK already exceeded MaxItems limit: throw ex; } } else { // let's custom build the Data object that includes the exception // along with the current HTTP request context: DTOs.Data data = new DTOs.Data( config: RollbarLocator.RollbarInstance.Config, body: new DTOs.Body(ex), custom: null, request: (context != null) ? new DTOs.Request(null, context.Request) : null ) { Level = ErrorLevel.Critical, }; // log the Data object (the exception + the HTTP request data): #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed RollbarLocator.RollbarInstance.Log(data); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } throw new System.Exception("The included internal exception processed by the Rollbar middleware", ex); } finally { if (context != null && context.Response != null && RollbarScope.Current != null && RollbarScope.Current.HttpContext != null && RollbarScope.Current.HttpContext.HttpAttributes != null ) { RollbarScope.Current.HttpContext.HttpAttributes.StatusCode = context.Response.StatusCode; } if (networkTelemetry != null) { if (string.IsNullOrWhiteSpace(networkTelemetry.StatusCode)) { networkTelemetry.StatusCode = context?.Response?.StatusCode.ToString(); } networkTelemetry.FinalizeEvent(); } } } }