public async Task Invoke(HttpContext context) { IScopeStatusManager scopeStatusManager = context.RequestServices.GetService <IScopeStatusManager>(); ILogger logger = context.RequestServices.GetService <ILogger>(); try { await Next.Invoke(context); string statusCode = context.Response.StatusCode.ToString(); bool responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason = statusCode.StartsWith("5"); bool responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason = statusCode.StartsWith("4"); if (responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason || responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason) { scopeStatusManager.MarkAsFailed(); logger.AddLogData("ResponseStatusCode", statusCode); if (responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason || context.Features.Get <IHttpResponseFeature>().ReasonPhrase == FoundationMetadataBuilder.KnownError) { await logger.LogWarningAsync("Response has failed status code because of some client side reason"); } else if (responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason) { await logger.LogFatalAsync("Response has failed status code because of some server side reason"); } } else if (!scopeStatusManager.WasSucceeded()) { await logger.LogFatalAsync("Scope was failed"); } else { scopeStatusManager.MarkAsSucceeded(); } } catch (Exception exp) { if (scopeStatusManager.WasSucceeded()) { scopeStatusManager.MarkAsFailed(); } await logger.LogExceptionAsync(exp, "Request-Execution-Exception"); string statusCode = context.Response.StatusCode.ToString(); bool responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason = statusCode.StartsWith("5"); bool responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason = statusCode.StartsWith("4"); if (responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason == false && responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason == false) { IExceptionToHttpErrorMapper exceptionToHttpErrorMapper = context.RequestServices.GetService <IExceptionToHttpErrorMapper>(); context.Response.StatusCode = Convert.ToInt32(exceptionToHttpErrorMapper.GetStatusCode(exp)); await context.Response.WriteAsync(exceptionToHttpErrorMapper.GetMessage(exp)); context.Features.Get <IHttpResponseFeature>().ReasonPhrase = exceptionToHttpErrorMapper.GetReasonPhrase(exp); } throw; } }
public virtual void Trace(HttpRequestMessage request, string category, TraceLevel level, Action <TraceRecord> traceAction) { if (request?.GetOwinContext() != null && (level == TraceLevel.Fatal || level == TraceLevel.Warn || level == TraceLevel.Error)) { TraceRecord traceRecord = new TraceRecord(request, category, level); traceAction(traceRecord); IDependencyResolver scopeDependencyResolver = request.GetOwinContext().GetDependencyResolver(); ILogger logger = scopeDependencyResolver.Resolve <ILogger>(); IScopeStatusManager scopeStatusManager = scopeDependencyResolver.Resolve <IScopeStatusManager>(); if (scopeStatusManager.WasSucceeded()) { scopeStatusManager.MarkAsFailed(); } if (traceRecord.Exception != null) { Exception exception = traceRecord.Exception; if (exception is TargetInvocationException && exception.InnerException != null) { exception = exception.InnerException; } if (!logger.LogData.Any(d => d.Key == "X-CorrelationId")) { logger.AddLogData("X-CorrelationId", request.GetCorrelationId()); } logger.AddLogData("WebExceptionType", exception.GetType().FullName); logger.AddLogData("WebException", exception); logger.AddLogData("WebApiErrorMessage", traceRecord.Message); } } }
public override Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken) { if (actionExecutedContext == null) { throw new ArgumentNullException(nameof(actionExecutedContext)); } IDependencyResolver scopeDependencyResolver = actionExecutedContext.Request.GetOwinContext().GetDependencyResolver(); IScopeStatusManager scopeStatusManager = scopeDependencyResolver.Resolve <IScopeStatusManager>(); IExceptionToHttpErrorMapper exceptionToHttpErrorMapper = scopeDependencyResolver.Resolve <IExceptionToHttpErrorMapper>(); Exception exception = actionExecutedContext.Exception; actionExecutedContext.Response = CreateErrorResponseMessage(actionExecutedContext, exceptionToHttpErrorMapper, exception); string reasonPhrase = exceptionToHttpErrorMapper.GetReasonPhrase(exception); actionExecutedContext.Response.ReasonPhrase = reasonPhrase; if (!actionExecutedContext.Response.Headers.Contains("Reason-Phrase")) { actionExecutedContext.Response.Headers.Add("Reason-Phrase", reasonPhrase); } if (scopeStatusManager.WasSucceeded()) { scopeStatusManager.MarkAsFailed(exception.Message); } return(base.OnExceptionAsync(actionExecutedContext, cancellationToken)); }
public override async Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken) { IDependencyResolver scopeDependencyResolver = actionExecutedContext.Request.GetOwinContext().GetDependencyResolver(); ILogger logger = scopeDependencyResolver.Resolve <ILogger>(); IScopeStatusManager scopeStatusManager = scopeDependencyResolver.Resolve <IScopeStatusManager>(); IExceptionToHttpErrorMapper exceptionToHttpErrorMapper = scopeDependencyResolver.Resolve <IExceptionToHttpErrorMapper>(); Exception exception = actionExecutedContext.Exception; actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(exceptionToHttpErrorMapper.GetStatusCode(exception), new ODataError() { Message = exceptionToHttpErrorMapper.GetMessage(exception) }); actionExecutedContext.Response.ReasonPhrase = exceptionToHttpErrorMapper.GetReasonPhrase(exception); if (scopeStatusManager.WasSucceeded()) { scopeStatusManager.MarkAsFailed(); } await base.OnExceptionAsync(actionExecutedContext, cancellationToken); }
public override Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken) { IDependencyResolver scopeDependencyResolver = actionExecutedContext.Request.GetOwinContext().GetDependencyResolver(); IScopeStatusManager scopeStatusManager = scopeDependencyResolver.Resolve <IScopeStatusManager>(); IExceptionToHttpErrorMapper exceptionToHttpErrorMapper = scopeDependencyResolver.Resolve <IExceptionToHttpErrorMapper>(); Exception exception = actionExecutedContext.Exception; actionExecutedContext.Response = CreateErrorResponseMessage(actionExecutedContext, exceptionToHttpErrorMapper, exception); actionExecutedContext.Response.ReasonPhrase = exceptionToHttpErrorMapper.GetReasonPhrase(exception); if (scopeStatusManager.WasSucceeded()) { scopeStatusManager.MarkAsFailed(exception.Message); } return(base.OnExceptionAsync(actionExecutedContext, cancellationToken)); }
public async Task Invoke(HttpContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } IScopeStatusManager scopeStatusManager = context.RequestServices.GetRequiredService <IScopeStatusManager>(); ILogger logger = context.RequestServices.GetRequiredService <ILogger>(); try { string?xCorrelationId = context.RequestServices.GetRequiredService <IRequestInformationProvider>().XCorrelationId; context.Response.OnStarting(() => { // See OnSendingHeaders of OwinExceptionHandlerMiddleware for more info. string?reasonPhrase = context.Features.Get <IHttpResponseFeature>().ReasonPhrase; bool responseIsOk = GetResponseStatus(context).responseIsOk; if (!responseIsOk) { if (string.IsNullOrEmpty(reasonPhrase)) { reasonPhrase = BitMetadataBuilder.UnknownError; } else if (!string.Equals(reasonPhrase, BitMetadataBuilder.KnownError, StringComparison.InvariantCultureIgnoreCase) && !string.Equals(reasonPhrase, BitMetadataBuilder.UnknownError, StringComparison.InvariantCultureIgnoreCase)) { reasonPhrase = $"{BitMetadataBuilder.UnknownError}:{reasonPhrase}"; } } if (!responseIsOk) { context.Features.Get <IHttpResponseFeature>().ReasonPhrase = reasonPhrase; if (!context.Response.Headers.ContainsKey("Reason-Phrase")) { context.Response.Headers.Add("Reason-Phrase", new[] { reasonPhrase }); } } if (!context.Response.Headers.ContainsKey("X-Correlation-ID")) { context.Response.Headers.Add("X-Correlation-ID", xCorrelationId); } return(Task.CompletedTask); }); await _next.Invoke(context).ConfigureAwait(false); var status = GetResponseStatus(context); if (status.responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason || status.responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason) { string?reasonPhrase = context.Features.Get <IHttpResponseFeature>().ReasonPhrase; scopeStatusManager.MarkAsFailed(reasonPhrase); logger.AddLogData("ResponseStatusCode", context.Response.StatusCode); logger.AddLogData("ResponseReasonPhrase", reasonPhrase); if (status.responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason || reasonPhrase == BitMetadataBuilder.KnownError) { await logger.LogWarningAsync("Response has failed status code because of some client side reason").ConfigureAwait(false); } else if (status.responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason) { await logger.LogFatalAsync("Response has failed status code because of some server side reason").ConfigureAwait(false); } } else if (!scopeStatusManager.WasSucceeded()) { await logger.LogFatalAsync($"Scope was failed: {scopeStatusManager.FailureReason}").ConfigureAwait(false); } else { scopeStatusManager.MarkAsSucceeded(); if (logger.Policy == LogPolicy.Always) { await logger.LogInformationAsync("Response succeded.").ConfigureAwait(false); } } } catch (Exception exp) { if (scopeStatusManager.WasSucceeded()) { scopeStatusManager.MarkAsFailed(exp.Message); } await logger.LogExceptionAsync(exp, "Request-Execution-Exception").ConfigureAwait(false); string statusCode = context.Response.StatusCode.ToString(CultureInfo.InvariantCulture); bool responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason = statusCode.StartsWith("5", StringComparison.InvariantCultureIgnoreCase); bool responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason = statusCode.StartsWith("4", StringComparison.InvariantCultureIgnoreCase); if (responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason == false && responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason == false) { IExceptionToHttpErrorMapper exceptionToHttpErrorMapper = context.RequestServices.GetRequiredService <IExceptionToHttpErrorMapper>(); context.Response.StatusCode = Convert.ToInt32(exceptionToHttpErrorMapper.GetStatusCode(exp), CultureInfo.InvariantCulture); context.Features.Get <IHttpResponseFeature>().ReasonPhrase = exceptionToHttpErrorMapper.GetReasonPhrase(exp); await context.Response.WriteAsync(exceptionToHttpErrorMapper.GetMessage(exp), context.RequestAborted).ConfigureAwait(false); } throw; } }
public override async Task Invoke(IOwinContext context) { IDependencyResolver dependencyResolver = context.GetDependencyResolver(); IScopeStatusManager scopeStatusManager = dependencyResolver.Resolve <IScopeStatusManager>(); ILogger logger = dependencyResolver.Resolve <ILogger>(); try { await Next.Invoke(context); string statusCode = context.Response.StatusCode.ToString(CultureInfo.InvariantCulture); bool responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason = statusCode.StartsWith("5", StringComparison.InvariantCultureIgnoreCase); bool responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason = statusCode.StartsWith("4", StringComparison.InvariantCultureIgnoreCase); if (responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason || responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason) { string reasonPhrase = context.Response.ReasonPhrase ?? "UnknownReasonPhrase"; scopeStatusManager.MarkAsFailed(reasonPhrase); logger.AddLogData("ResponseStatusCode", statusCode); logger.AddLogData("ResponseReasonPhrase", reasonPhrase); if (responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason || reasonPhrase == BitMetadataBuilder.KnownError) { await logger.LogWarningAsync("Response has failed status code because of some client side reason"); } else if (responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason) { await logger.LogFatalAsync("Response has failed status code because of some server side reason"); } } else if (!scopeStatusManager.WasSucceeded()) { await logger.LogFatalAsync($"Scope was failed: {scopeStatusManager.FailureReason}"); } else { scopeStatusManager.MarkAsSucceeded(); } } catch (Exception exp) { if (scopeStatusManager.WasSucceeded()) { scopeStatusManager.MarkAsFailed(exp.Message); } await logger.LogExceptionAsync(exp, "Request-Execution-Exception"); string statusCode = context.Response.StatusCode.ToString(CultureInfo.InvariantCulture); bool responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason = statusCode.StartsWith("5", StringComparison.InvariantCultureIgnoreCase); bool responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason = statusCode.StartsWith("4", StringComparison.InvariantCultureIgnoreCase); if (responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason == false && responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason == false) { IExceptionToHttpErrorMapper exceptionToHttpErrorMapper = dependencyResolver.Resolve <IExceptionToHttpErrorMapper>(); context.Response.StatusCode = Convert.ToInt32(exceptionToHttpErrorMapper.GetStatusCode(exp), CultureInfo.InvariantCulture); await context.Response.WriteAsync(exceptionToHttpErrorMapper.GetMessage(exp), context.Request.CallCancelled); context.Response.ReasonPhrase = exceptionToHttpErrorMapper.GetReasonPhrase(exp); } throw; } }
public override async Task Invoke(IOwinContext context) { IDependencyResolver dependencyResolver = context.GetDependencyResolver(); IScopeStatusManager scopeStatusManager = dependencyResolver.Resolve <IScopeStatusManager>(); ILogger logger = dependencyResolver.Resolve <ILogger>(); try { context.Response.OnSendingHeaders((state) => { // Create a backup header for reason phrase + enhance its value if possible. // We're able to modify reason phrase and other headers in this callback and in catch part of this class only. // We may not change response headers after await Next.Invoke(context); Codes after Next.Invoke gets invoked after OnSendingHeaders. string reasonPhrase = context.Response.ReasonPhrase; // It can gets filled by // 1- WebApi's routing, when no routing gets matched with value "Not Found". // 2- In catch part of this class with either "KnownError" & "UnknownError" values. // 3- In ExceptionHandlerFilterAttribute class with either "KnownError" & "UnknownError" values. // 4- Other codes! It might be empty too! bool responseIsOk = GetResponseStatus(context).responseIsOk; if (!responseIsOk) { if (string.IsNullOrEmpty(reasonPhrase)) { reasonPhrase = BitMetadataBuilder.UnknownError; } else if (!string.Equals(reasonPhrase, BitMetadataBuilder.KnownError, StringComparison.CurrentCultureIgnoreCase) && !string.Equals(reasonPhrase, BitMetadataBuilder.UnknownError, StringComparison.CurrentCultureIgnoreCase)) { reasonPhrase = $"{BitMetadataBuilder.UnknownError}:{reasonPhrase}"; } } if (!responseIsOk) { context.Response.ReasonPhrase = reasonPhrase; if (!context.Response.Headers.ContainsKey("Reason-Phrase")) { context.Response.Headers.Add("Reason-Phrase", new[] { reasonPhrase }); } } }, state: null); await Next.Invoke(context); var status = GetResponseStatus(context); if (status.responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason || status.responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason) { string reasonPhrase = context.Response.ReasonPhrase; scopeStatusManager.MarkAsFailed(reasonPhrase); logger.AddLogData("ResponseStatusCode", context.Response.StatusCode); logger.AddLogData("ResponseReasonPhrase", reasonPhrase); if (status.responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason || reasonPhrase == BitMetadataBuilder.KnownError) { await logger.LogWarningAsync("Response has failed status code because of some client side reason"); } else if (status.responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason) { await logger.LogFatalAsync("Response has failed status code because of some server side reason"); } } else if (!scopeStatusManager.WasSucceeded()) { await logger.LogFatalAsync($"Scope was failed: {scopeStatusManager.FailureReason}"); } else { scopeStatusManager.MarkAsSucceeded(); } } catch (Exception exp) { if (scopeStatusManager.WasSucceeded()) { scopeStatusManager.MarkAsFailed(exp.Message); } await logger.LogExceptionAsync(exp, "Request-Execution-Exception"); string statusCode = context.Response.StatusCode.ToString(CultureInfo.InvariantCulture); bool responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason = statusCode.StartsWith("5", StringComparison.InvariantCultureIgnoreCase); bool responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason = statusCode.StartsWith("4", StringComparison.InvariantCultureIgnoreCase); if (responseStatusCodeIsErrorCodeBecauseOfSomeClientBasedReason == false && responseStatusCodeIsErrorCodeBecauseOfSomeServerBasedReason == false) { IExceptionToHttpErrorMapper exceptionToHttpErrorMapper = dependencyResolver.Resolve <IExceptionToHttpErrorMapper>(); context.Response.StatusCode = Convert.ToInt32(exceptionToHttpErrorMapper.GetStatusCode(exp), CultureInfo.InvariantCulture); context.Response.ReasonPhrase = exceptionToHttpErrorMapper.GetReasonPhrase(exp); await context.Response.WriteAsync(exceptionToHttpErrorMapper.GetMessage(exp), context.Request.CallCancelled); } throw; } }