Пример #1
0
        /// <summary>
        /// Handles the exception by responding appropriately with error page with conditional level of details and logging
        /// </summary>
        public static void HandleException(WorkContext work,
                                           Exception error,
                                           OrderedRegistry <WorkMatch> showDumpMatches,
                                           OrderedRegistry <WorkMatch> logMatches,
                                           string securityRedirectURL    = null,
                                           string securityRedirectTarget = null,
                                           OrderedRegistry <WorkMatch> securityRedirectMatches = null,
                                           Type customPageType = null
                                           )
        {
            if (work == null || error == null)
            {
                return;
            }

            var showDump = showDumpMatches != null?
                           showDumpMatches.OrderedValues.Any(m => m.Make(work) != null) : false;

            if (work.Response.Buffered)
            {
                work.Response.CancelBuffered();
            }

            var json = false;

            if (work.Request != null && work.Request.AcceptTypes != null)//if needed for some edge HttpListener cases when Request or Request.AcceptTypes are null
            {
                json = work.Request.AcceptTypes.Any(at => at.EqualsIgnoreCase(ContentType.JSON));
            }

            var actual = error;

            if (actual is FilterPipelineException fpe)
            {
                actual = fpe.RootException;
            }

            if (actual is MvcException mvce)
            {
                actual = mvce.InnerException;
            }


            var securityError = Security.AuthorizationException.IsDenotedBy(actual);


            if (actual is IHttpStatusProvider httpStatusProvider)
            {
                work.Response.StatusCode        = httpStatusProvider.HttpStatusCode;
                work.Response.StatusDescription = httpStatusProvider.HttpStatusDescription;
            }
            else
            {
                if (securityError)
                {
                    work.Response.StatusCode        = WebConsts.STATUS_403;
                    work.Response.StatusDescription = WebConsts.STATUS_403_DESCRIPTION;
                }
                else
                {
                    work.Response.StatusCode        = WebConsts.STATUS_500;
                    work.Response.StatusDescription = WebConsts.STATUS_500_DESCRIPTION;
                }
            }


            if (json)
            {
                work.Response.ContentType = ContentType.JSON;
                work.Response.WriteJSON(error.ToClientResponseJSONMap(showDump));
            }
            else
            {
                if (securityRedirectMatches != null && securityRedirectMatches.Count > 0)
                {
                    JsonDataMap matched = null;
                    foreach (var match in securityRedirectMatches.OrderedValues)
                    {
                        matched = match.Make(work, actual);
                        if (matched != null)
                        {
                            break;
                        }
                    }
                    if (matched != null)
                    {
                        var url    = matched[VAR_SECURITY_REDIRECT_URL].AsString();
                        var target = matched[VAR_SECURITY_REDIRECT_TARGET].AsString();

                        if (url.IsNotNullOrWhiteSpace())
                        {
                            securityRedirectURL = url;
                        }
                        if (target.IsNotNullOrWhiteSpace())
                        {
                            securityRedirectTarget = target;
                        }
                    }
                }

                if (securityRedirectURL.IsNotNullOrWhiteSpace() && securityError && !work.IsAuthenticated)
                {
                    var url    = securityRedirectURL;
                    var target = securityRedirectTarget;
                    if (target.IsNotNullOrWhiteSpace())
                    {
                        var partsA = url.Split('#');
                        var parts  = partsA[0].Split('?');
                        var query  = parts.Length > 1 ? parts[0] + "&" : string.Empty;
                        url = "{0}?{1}{2}={3}{4}".Args(parts[0], query,
                                                       target, Uri.EscapeDataString(work.Request.Url.PathAndQuery),
                                                       partsA.Length > 1 ? "#" + partsA[1] : string.Empty);
                    }
                    work.Response.RedirectAndAbort(url);
                }
                else
                {
                    WaveTemplate errorPage = null;

                    if (customPageType != null)
                    {
                        try
                        {
                            errorPage = Activator.CreateInstance(customPageType) as WaveTemplate;
                            if (errorPage == null)
                            {
                                throw new WaveException("not WaveTemplate");
                            }
                        }
                        catch (Exception actErr)
                        {
                            work.Log(Log.MessageType.Error,
                                     StringConsts.ERROR_PAGE_TEMPLATE_TYPE_ERROR.Args(customPageType.FullName, actErr.ToMessageWithType()),
                                     typeof(ErrorFilter).FullName + ".ctor(customPageType)",
                                     actErr);
                        }
                    }

                    if (errorPage == null)
                    {
                        errorPage = new ErrorPage(work, error, showDump);
                    }

                    errorPage.Render(work, error);
                }
            }

            if (logMatches != null && logMatches.Count > 0)
            {
                JsonDataMap matched = null;
                foreach (var match in logMatches.OrderedValues)
                {
                    matched = match.Make(work, error);
                    if (matched != null)
                    {
                        break;
                    }
                }
                if (matched != null)
                {
                    work.Log(Log.MessageType.Error, error.ToMessageWithType(), typeof(ErrorFilter).FullName, pars: matched.ToJson(JsonWritingOptions.CompactASCII));
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Handles the exception by responding appropriately with error page with conditional level of details and logging
        /// </summary>
        public static void HandleException(WorkContext work,
                                           Exception error,
                                           OrderedRegistry <WorkMatch> showDumpMatches,
                                           OrderedRegistry <WorkMatch> logMatches,
                                           string securityRedirectURL    = null,
                                           string securityRedirectTarget = null,
                                           OrderedRegistry <WorkMatch> securityRedirectMatches = null,
                                           Type customPageType = null
                                           )
        {
            if (work == null || error == null)
            {
                return;
            }

            var showDump = showDumpMatches != null?
                           showDumpMatches.OrderedValues.Any(m => m.Make(work) != null) : false;

            if (work.Response.Buffered)
            {
                work.Response.CancelBuffered();
            }

            var json = false;

            if (work.Request != null && work.Request.AcceptTypes != null)//if needed for some edge HttpListener cases when Request or Request.AcceptTypes are null
            {
                json = work.Request.AcceptTypes.Any(at => at.EqualsIgnoreCase(ContentType.JSON));
            }

            var actual = error;

            if (actual is FilterPipelineException fpe)
            {
                actual = fpe.RootException;
            }

            if (actual is MvcException mvce)
            {
                actual = mvce.InnerException;
            }


            var securityError = Security.AuthorizationException.IsDenotedBy(error);

            var hsp = error.SearchThisOrInnerExceptionOf <IHttpStatusProvider>();

            if (hsp != null)
            {
                work.Response.StatusCode        = hsp.HttpStatusCode;
                work.Response.StatusDescription = hsp.HttpStatusDescription;
            }
            else
            {
                if (securityError)
                {
                    work.Response.StatusCode        = WebConsts.STATUS_403;
                    work.Response.StatusDescription = WebConsts.STATUS_403_DESCRIPTION;
                }
                else
                {
                    work.Response.StatusCode        = WebConsts.STATUS_500;
                    work.Response.StatusDescription = WebConsts.STATUS_500_DESCRIPTION;
                }
            }


            if (json)
            {
                work.Response.ContentType = ContentType.JSON;
                work.Response.WriteJSON(error.ToClientResponseJsonMap(showDump), JsonWritingOptions.PrettyPrintRowsAsMap);
            }
            else
            {
                if (securityRedirectMatches != null && securityRedirectMatches.Count > 0)
                {
                    JsonDataMap matched = null;
                    foreach (var match in securityRedirectMatches.OrderedValues)
                    {
                        matched = match.Make(work, actual);
                        if (matched != null)
                        {
                            break;
                        }
                    }
                    if (matched != null)
                    {
                        var url    = matched[VAR_SECURITY_REDIRECT_URL].AsString();
                        var target = matched[VAR_SECURITY_REDIRECT_TARGET].AsString();

                        if (url.IsNotNullOrWhiteSpace())
                        {
                            securityRedirectURL = url;
                        }
                        if (target.IsNotNullOrWhiteSpace())
                        {
                            securityRedirectTarget = target;
                        }
                    }
                }

                if (securityRedirectURL.IsNotNullOrWhiteSpace() && securityError && !work.IsAuthenticated)
                {
                    var url    = securityRedirectURL;
                    var target = securityRedirectTarget;
                    if (target.IsNotNullOrWhiteSpace())
                    {
                        var partsA = url.Split('#');
                        var parts  = partsA[0].Split('?');
                        var query  = parts.Length > 1 ? parts[0] + "&" : string.Empty;
                        url = "{0}?{1}{2}={3}{4}".Args(parts[0], query,
                                                       target, Uri.EscapeDataString(work.Request.Url.PathAndQuery),
                                                       partsA.Length > 1 ? "#" + partsA[1] : string.Empty);
                    }
                    work.Response.RedirectAndAbort(url);
                }
                else
                {
                    WaveTemplate errorPage = null;

                    if (customPageType != null)
                    {
                        try
                        {
                            //20201130 DKh fix #376
                            var simpleCtor = customPageType.GetConstructor(new Type[] { typeof(Exception), typeof(bool) }) == null;
                            errorPage = (simpleCtor ? Activator.CreateInstance(customPageType) :
                                         Activator.CreateInstance(customPageType, error, showDump)
                                         ) as WaveTemplate;//fix #376

                            if (errorPage == null)
                            {
                                throw new WaveException("not a {0}".Args(nameof(WaveTemplate)));
                            }
                        }
                        catch (Exception actErr)
                        {
                            work.Log(Log.MessageType.Error,
                                     StringConsts.ERROR_PAGE_TEMPLATE_TYPE_ERROR.Args(customPageType.FullName, actErr.ToMessageWithType()),
                                     typeof(ErrorFilter).FullName + ".ctor(customPageType)",
                                     actErr);
                        }
                    }

                    if (errorPage == null)
                    {
                        errorPage = new ErrorPage(error, showDump);
                    }

                    errorPage.Render(work, error);
                }
            }

            if (logMatches != null && logMatches.Count > 0)
            {
                JsonDataMap matched = null;
                foreach (var match in logMatches.OrderedValues)
                {
                    matched = match.Make(work, error);
                    if (matched != null)
                    {
                        break;
                    }
                }
                if (matched != null)
                {
                    matched["$ip"]   = work.EffectiveCallerIPEndPoint.ToString();
                    matched["$ua"]   = work.Request.UserAgent.TakeFirstChars(78, "..");
                    matched["$mtd"]  = work.Request.HttpMethod;
                    matched["$uri"]  = work.Request.Url.ToString().TakeFirstChars(78, "..");
                    matched["$ref"]  = work.Request.UrlReferrer?.ToString().TakeFirstChars(78, "..");
                    matched["$stat"] = "{0}/{1}".Args(work.Response.StatusCode, work.Response.StatusDescription);

                    if (work.Portal != null)
                    {
                        matched["$portal"] = work.Portal.Name;
                    }

                    if (work.GeoEntity != null)
                    {
                        matched["$geo"] = work.GeoEntity.LocalityName;
                    }

                    work.Log(Log.MessageType.Error, error.ToMessageWithType(), typeof(ErrorFilter).FullName, pars: matched.ToJson(JsonWritingOptions.CompactASCII));
                }
            }
        }