public async Task ExceptionHandlerMustSaveWarningToLogStoreBecauseOfErrorRelatedToClientRequest()
        {
            using (BitOwinTestEnvironment testEnvironment = new BitOwinTestEnvironment())
            {
                TokenResponse token = await testEnvironment.Server.Login("ValidUserName", "ValidPassword", clientId : "TestResOwner");

                await testEnvironment.Server.BuildHttpClient(token)
                .GetAsync("/odata/Test/XYZ");

                IScopeStatusManager scopeStatusManager = TestDependencyManager.CurrentTestDependencyManager
                                                         .Objects.OfType <IScopeStatusManager>()
                                                         .Last();

                A.CallTo(() => scopeStatusManager.MarkAsFailed("Not Acceptable"))
                .MustHaveHappened(Repeated.Exactly.Once);

                ILogger logger = TestDependencyManager.CurrentTestDependencyManager
                                 .Objects.OfType <ILogger>()
                                 .Last();

                A.CallTo(() => logger.LogWarningAsync(A <string> .Ignored))
                .MustHaveHappened(Repeated.Exactly.Once);

                LogData[] logData = logger.LogData.ToArray();

                logData.Single(c => c.Key == "ResponseStatusCode" && (string)c.Value == "406");
                logData.Single(c => c.Key == nameof(IRequestInformationProvider.HttpMethod) && (string)c.Value == "GET");
                logData.Single(c => c.Key == "UserId" && (string)c.Value == "ValidUserName");
            }
        }
        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);
        }
示例#3
0
        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);
                }
            }
        }
示例#4
0
        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));
        }
示例#5
0
        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 DefaultDbConnectionProvider(IScopeStatusManager scopeStatusManager)
        {
            if (scopeStatusManager == null)
            {
                throw new ArgumentNullException(nameof(scopeStatusManager));
            }

            _scopeStatusManager = scopeStatusManager;
        }
示例#7
0
        public DefaultUnitOfWork(IScopeStatusManager scopeStatusManager)
        {
            if (scopeStatusManager == null)
            {
                throw new ArgumentNullException(nameof(scopeStatusManager));
            }

            _scopeStatusManager = scopeStatusManager;
        }
        public async Task ExceptionHandlerMustNotSaveAnyThingToLogStoreBecauseOfSuccessfulRequests()
        {
            using (BitOwinTestEnvironment testEnvironment = new BitOwinTestEnvironment())
            {
                await testEnvironment.Server.Login("ValidUserName", "ValidPassword", clientId : "TestResOwner");

                IScopeStatusManager scopeStatusManager = testEnvironment.GetObjects <IScopeStatusManager>()
                                                         .Single();

                A.CallTo(() => scopeStatusManager.MarkAsSucceeded())
                .MustHaveHappenedOnceExactly();
            }
        }
        public async Task ExceptionHandlerMustNotSaveAnyThingToLogStoreBecauseOfSuccessfulRequests()
        {
            using (TestEnvironment testEnvironment = new TestEnvironment())
            {
                testEnvironment.Server.Login("ValidUserName", "ValidPassword");

                IScopeStatusManager scopeStatusManager = TestDependencyManager.CurrentTestDependencyManager
                                                         .Objects.OfType <IScopeStatusManager>()
                                                         .Single();

                A.CallTo(() => scopeStatusManager.MarkAsSucceeded())
                .MustHaveHappened(Repeated.Exactly.Once);
            }
        }
        public async Task ExceptionHandlerMustSaveExceptionToLogStoreBecauseOfExceptionInRequest()
        {
            using (BitOwinTestEnvironment testEnvironment = new BitOwinTestEnvironment(new TestEnvironmentArgs
            {
                AdditionalDependencies = (manager, services) =>
                {
                    manager.RegisterOwinMiddlewareUsing(owinApp =>
                    {
                        owinApp.Map("/Exception", innerApp =>
                        {
                            innerApp.Use <ExceptionThrownMiddleware>();
                        });
                    });
                }
            }))
            {
                try
                {
                    TokenResponse token = await testEnvironment.Server.Login("ValidUserName", "ValidPassword", clientId : "TestResOwner");

                    await testEnvironment.Server.BuildHttpClient(token)
                    .GetAsync("/Exception");

                    Assert.Fail();
                }
                catch
                {
                    IScopeStatusManager scopeStatusManager = TestDependencyManager.CurrentTestDependencyManager
                                                             .Objects.OfType <IScopeStatusManager>()
                                                             .Last();

                    A.CallTo(() => scopeStatusManager.MarkAsFailed("Operation is not valid due to the current state of the object."))
                    .MustHaveHappened(Repeated.Exactly.Once);

                    ILogger logger = TestDependencyManager.CurrentTestDependencyManager
                                     .Objects.OfType <ILogger>()
                                     .Last();

                    A.CallTo(() => logger.LogExceptionAsync(A <Exception> .That.Matches(e => e is InvalidOperationException), A <string> .Ignored))
                    .MustHaveHappened(Repeated.Exactly.Once);

                    LogData[] logData = logger.LogData.ToArray();

                    logData.Single(c => c.Key == "ExceptionType" && ((string)c.Value).Contains("InvalidOperationException"));
                    logData.Single(c => c.Key == nameof(IRequestInformationProvider.HttpMethod) && (string)c.Value == "GET");
                    logData.Single(c => c.Key == "UserId" && (string)c.Value == "ValidUserName");
                }
            }
        }
        public async Task ExceptionHandlerMustSaveFatalToLogStoreBecauseOfErrorRelatedToServer()
        {
            using (BitOwinTestEnvironment testEnvironment = new BitOwinTestEnvironment(new TestEnvironmentArgs
            {
                AdditionalDependencies = (manager, services) =>
                {
                    manager.RegisterOwinMiddlewareUsing(owinApp =>
                    {
                        owinApp.Map("/InternalServerError", innerApp =>
                        {
                            innerApp.Use <InternalServerErrorMiddleware>();
                        });
                    });
                }
            }))
            {
                TokenResponse token = await testEnvironment.Server.Login("ValidUserName", "ValidPassword", clientId : "TestResOwner");

                await testEnvironment.Server.BuildHttpClient(token)
                .GetAsync("/InternalServerError");

                IScopeStatusManager scopeStatusManager = TestDependencyManager.CurrentTestDependencyManager
                                                         .Objects.OfType <IScopeStatusManager>()
                                                         .Last();

                A.CallTo(() => scopeStatusManager.MarkAsFailed("UnknownReasonPhrase"))
                .MustHaveHappened(Repeated.Exactly.Once);

                ILogger logger = TestDependencyManager.CurrentTestDependencyManager
                                 .Objects.OfType <ILogger>()
                                 .Last();

                A.CallTo(() => logger.LogFatalAsync(A <string> .Ignored))
                .MustHaveHappened(Repeated.Exactly.Once);

                LogData[] logData = logger.LogData.ToArray();

                logData.Single(c => c.Key == "ResponseStatusCode" && (string)c.Value == "501");
                logData.Single(c => c.Key == nameof(IRequestInformationProvider.HttpMethod) && (string)c.Value == "GET");
                logData.Single(c => c.Key == "UserId" && (string)c.Value == "ValidUserName");
            }
        }
示例#12
0
        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;
            }
        }
示例#15
0
        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;
            }
        }