예제 #1
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;
            }
        }
예제 #2
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);
                }
            }
        }
예제 #3
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));
        }
        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);
        }
예제 #5
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;
            }
        }
예제 #8
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;
            }
        }